ETH Price: $2,113.23 (+4.25%)

Contract

0xD912d922E7E6d11d5caaE204f7907F38E70AbEd2
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Advanced mode:
Parent Transaction Hash Method Block
From
To
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CLeverAMOHarvesterFacet

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.6;

import "../../concentrator/clever/interfaces/ICLeverAMO.sol";

import "../libraries/LibConcentratorHarvester.sol";

contract CLeverAMOHarvesterFacet {
  /// @notice Harvest pending rewards from CLeverAMO contract.
  /// @param _amo The address of CLeverAMO contract.
  /// @param _minBaseOut The minimum of base token should harvested.
  function harvestCLeverAMO(address _amo, uint256 _minBaseOut) external {
    LibConcentratorHarvester.enforceHasPermission();

    ICLeverAMO(_amo).harvest(msg.sender, _minBaseOut);
  }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.6;
pragma abicoder v2;

import "../../interfaces/ICurveVoteEscrow.sol";

// solhint-disable const-name-snakecase
// solhint-disable no-inline-assembly
// solhint-disable not-rely-on-time

library LibConcentratorHarvester {
  /*************
   * Constants *
   *************/

  /// @dev The storage slot for default diamond storage.
  bytes32 private constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

  /// @dev The storage slot for harvester storage.
  bytes32 private constant HARVESTER_STORAGE_POSITION = keccak256("diamond.harvester.concentrator.storage");

  /// @dev The address of veCTR contract.
  address internal constant veCTR = 0xe4C09928d834cd58D233CD77B5af3545484B4968;

  /***********
   * Structs *
   ***********/

  struct FacetAddressAndSelectorPosition {
    address facetAddress;
    uint16 selectorPosition;
  }

  struct DiamondStorage {
    // function selector => facet address and selector position in selectors array
    mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition;
    bytes4[] selectors;
    mapping(bytes4 => bool) supportedInterfaces;
    // owner of the contract
    address contractOwner;
  }

  struct HarvesterStorage {
    uint128 minLockCTR;
    uint128 minLockDuration;
    mapping(address => bool) whitelist;
    mapping(address => bool) blacklist;
  }

  /**********************
   * Internal Functions *
   **********************/

  function diamondStorage() private pure returns (DiamondStorage storage ds) {
    bytes32 position = DIAMOND_STORAGE_POSITION;
    assembly {
      ds.slot := position
    }
  }

  function harvesterStorage() internal pure returns (HarvesterStorage storage hs) {
    bytes32 position = HARVESTER_STORAGE_POSITION;
    assembly {
      hs.slot := position
    }
  }

  function updatePermission(uint128 _minLockCTR, uint128 _minLockDuration) internal {
    HarvesterStorage storage hs = harvesterStorage();

    hs.minLockCTR = _minLockCTR;
    hs.minLockDuration = _minLockDuration;
  }

  function updateWhitelist(address _account, bool _status) internal {
    HarvesterStorage storage hs = harvesterStorage();

    hs.whitelist[_account] = _status;
  }

  function updateBlacklist(address _account, bool _status) internal {
    HarvesterStorage storage hs = harvesterStorage();

    hs.blacklist[_account] = _status;
  }

  function enforceIsContractOwner() internal view {
    require(msg.sender == diamondStorage().contractOwner, "only owner");
  }

  function enforceHasPermission() internal view {
    ICurveVoteEscrow.LockedBalance memory _locked = ICurveVoteEscrow(veCTR).locked(msg.sender);
    HarvesterStorage storage hs = harvesterStorage();

    // check whether is blacklisted
    require(!hs.blacklist[msg.sender], "account blacklisted");

    // check whether is whitelisted
    if (hs.whitelist[msg.sender] || hs.minLockCTR == 0) return;

    // check veCTR locking
    require(uint128(_locked.amount) >= hs.minLockCTR, "insufficient lock amount");
    require(_locked.end >= hs.minLockDuration + block.timestamp, "insufficient lock duration");
  }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.6;

interface ICLeverAMO {
  /// @notice Emitted when someone deposit base token to the contract.
  /// @param owner The owner of the base token.
  /// @param recipient The recipient of the locked base token.
  /// @param amount The amount of base token deposited.
  /// @param unlockAt The timestamp in second when the pool share is unlocked.
  event Deposit(address indexed owner, address indexed recipient, uint256 amount, uint256 unlockAt);

  /// @notice Emitted when someone unlock base token to pool share.
  /// @param owner The owner of the locked base token.
  /// @param amount The amount of base token unlocked.
  /// @param share The amount of pool share received.
  /// @param ratio The current ratio between lp token and debt token in the contract.
  event Unlock(address indexed owner, uint256 amount, uint256 share, uint256 ratio);

  /// @notice Emitted when someone withdraw pool share.
  /// @param owner The owner of the pool share.
  /// @param recipient The recipient of the withdrawn debt token and lp token.
  /// @param shares The amount of pool share to withdraw.
  /// @param debtAmount The current amount of debt token received.
  /// @param lpAmount The current amount of lp token received.
  /// @param ratio The current ratio between lp token and debt token in the contract.
  event Withdraw(
    address indexed owner,
    address indexed recipient,
    uint256 shares,
    uint256 debtAmount,
    uint256 lpAmount,
    uint256 ratio
  );

  /// @notice Emitted when someone call harvest.
  /// @param caller The address of the caller.
  /// @param baseAmount The amount of base token harvested.
  /// @param platformFee The amount of platform fee.
  /// @param bounty The amount of base token as harvest bounty.
  /// @param debtAmount The current amount of debt token harvested.
  /// @param lpAmount The current amount of lp token harvested.
  /// @param ratio The current ratio between lp token and debt token in the contract.
  event Harvest(
    address indexed caller,
    uint256 baseAmount,
    uint256 platformFee,
    uint256 bounty,
    uint256 debtAmount,
    uint256 lpAmount,
    uint256 ratio
  );

  /// @notice Emitted when someone checkpoint AMO state.
  /// @param baseAmount The amount of base token used to convert.
  /// @param debtAmount The current amount of debt token converted.
  /// @param lpAmount The current amount of lp token converted.
  /// @param ratio The current ratio between lp token and debt token in the contract.
  event Checkpoint(uint256 baseAmount, uint256 debtAmount, uint256 lpAmount, uint256 ratio);

  /// @notice Emitted when someone donate base token to the contract.
  /// @param caller The address of the caller.
  /// @param amount The amount of base token donated.
  event Donate(address indexed caller, uint256 amount);

  /// @notice Emitted when someone call rebalance.
  /// @param ratio The current ratio between lp token and debt token in the contract.
  /// @param startPoolRatio The ratio between debt token and base token in curve pool before rebalance.
  /// @param targetPoolRatio The ratio between debt token and base token in curve pool after rebalance.
  event Rebalance(uint256 ratio, uint256 startPoolRatio, uint256 targetPoolRatio);

  /// @notice The address of base token.
  function baseToken() external view returns (address);

  /// @notice The address of debt token.
  function debtToken() external view returns (address);

  /// @notice The address of Curve base/debt pool.
  function curvePool() external view returns (address);

  /// @notice The address of Curve base/debt lp token.
  function curveLpToken() external view returns (address);

  /// @notice The address of furnace contract for debt token.
  function furnace() external view returns (address);

  /// @notice The total amount of debt token in contract.
  function totalDebtToken() external view returns (uint256);

  /// @notice The total amount of curve lp token in contract.
  function totalCurveLpToken() external view returns (uint256);

  /// @notice The current ratio between curve lp token and debt token, with precision 1e18.
  function ratio() external view returns (uint256);

  /// @notice Deposit base token to the contract.
  /// @dev Use `_amount` when caller wants to deposit all his base token.
  /// @param _amount The amount of base token to deposit.
  /// @param _recipient The address recipient who will receive the base token.
  function deposit(uint256 _amount, address _recipient) external;

  /// @notice Unlock pool share from the contract.
  /// @param _minShareOut The minimum amount of shares should receive.
  /// @return shares The amount of shares received.
  function unlock(uint256 _minShareOut) external returns (uint256 shares);

  /// @notice Burn shares and withdraw to debt token and lp token according to current ratio.
  /// @dev Use `_shares` when caller wants to withdraw all his shares.
  /// @param _shares The amount of pool shares to burn.
  /// @param _recipient The address of recipient who will receive the token.
  /// @param _minLpOut The minimum of lp token should receive.
  /// @param _minDebtOut The minimum of debt token should receive.
  /// @return lpTokenOut The amount of lp token received.
  /// @return debtTokenOut The amount of debt token received.
  function withdraw(
    uint256 _shares,
    address _recipient,
    uint256 _minLpOut,
    uint256 _minDebtOut
  ) external returns (uint256 lpTokenOut, uint256 debtTokenOut);

  /// @notice Burn shares and withdraw to base token.
  /// @dev Use `_shares` when caller wants to withdraw all his shares.
  /// @param _shares The amount of pool shares to burn.
  /// @param _recipient The address of recipient who will receive the token.
  /// @param _minBaseOut The minimum of base token should receive.
  /// @return baseTokenOut The amount of base token received.
  function withdrawToBase(
    uint256 _shares,
    address _recipient,
    uint256 _minBaseOut
  ) external returns (uint256 baseTokenOut);

  /// @notice Someone donate base token to the contract.
  /// @param _amount The amount of base token to donate.
  function donate(uint256 _amount) external;

  /// @notice rebalance the curve pool based on tokens in curve pool.
  /// @param _withdrawAmount The amount of debt token or lp token to withdraw.
  /// @param _minOut The minimum output token to control slippage.
  /// @param _targetRangeLeft The left end point of the target range, multiplied by 1e18.
  /// @param _targetRangeRight The right end point of the target range, multiplied by 1e18.
  function rebalance(
    uint256 _withdrawAmount,
    uint256 _minOut,
    uint256 _targetRangeLeft,
    uint256 _targetRangeRight
  ) external;

  /// @notice harvest the pending rewards and reinvest to the pool.
  /// @param _recipient The address of recipient who will receive the harvest bounty.
  /// @param _minBaseOut The minimum of base token should harvested.
  /// @return baseTokenOut The amount of base token harvested.
  function harvest(address _recipient, uint256 _minBaseOut) external returns (uint256 baseTokenOut);

  /// @notice External call to checkpoint AMO state.
  function checkpoint() external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.6;
pragma abicoder v2;

// solhint-disable func-name-mixedcase
// solhint-disable var-name-mixedcase

interface ICurveVoteEscrow {
  struct LockedBalance {
    int128 amount;
    uint256 end;
  }

  /// @notice Deposit `_value` tokens for `msg.sender` and lock until `_unlock_time`
  /// @param _value Amount to deposit
  /// @param _unlock_time Epoch time when tokens unlock, rounded down to whole weeks
  function create_lock(uint256 _value, uint256 _unlock_time) external;

  /// @notice Deposit `_value` additional tokens for `msg.sender` without modifying the unlock time
  /// @param _value Amount of tokens to deposit and add to the lock
  function increase_amount(uint256 _value) external;

  /// @notice Extend the unlock time for `msg.sender` to `_unlock_time`
  /// @param _unlock_time New epoch time for unlocking
  function increase_unlock_time(uint256 _unlock_time) external;

  /// @notice Withdraw all tokens for `msg.sender`
  /// @dev Only possible if the lock has expired
  function withdraw() external;

  /// @notice Get timestamp when `_addr`'s lock finishes
  /// @param _addr User wallet
  /// @return Epoch time of the lock end
  function locked__end(address _addr) external view returns (uint256);

  function locked(address _addr) external view returns (LockedBalance memory);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_amo","type":"address"},{"internalType":"uint256","name":"_minBaseOut","type":"uint256"}],"name":"harvestCLeverAMO","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506103bb806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80637edadc0414610030575b600080fd5b61005c6004803603604081101561004657600080fd5b506001600160a01b03813516906020013561005e565b005b6100666100e5565b6040805163018ee9b760e01b81523360048201526024810183905290516001600160a01b0384169163018ee9b79160448083019260209291908290030181600087803b1580156100b557600080fd5b505af11580156100c9573d6000803e3d6000fd5b505050506040513d60208110156100df57600080fd5b50505050565b60405163cbf9fe5f60e01b815260009073e4c09928d834cd58d233cd77b5af3545484b49689063cbf9fe5f9061011f9033906004016102d6565b604080518083038186803b15801561013657600080fd5b505afa15801561014a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016e919061027f565b9050600061017a61025b565b33600090815260028201602052604090205490915060ff16156101b85760405162461bcd60e51b81526004016101af906102ea565b60405180910390fd5b33600090815260018201602052604090205460ff16806101e0575080546001600160801b0316155b156101ec575050610259565b805482516001600160801b039182169116101561021b5760405162461bcd60e51b81526004016101af90610317565b805460208301516001600160801b03600160801b90920491909116420111156102565760405162461bcd60e51b81526004016101af9061034e565b50505b565b7f7b3d7c6d072f5ba80c1b8069e5afa5580d5083ebf8116656029468cd718daac790565b600060408284031215610290578081fd5b6040516040810181811067ffffffffffffffff821117156102ad57fe5b6040528251600f81900b81146102c1578283fd5b81526020928301519281019290925250919050565b6001600160a01b0391909116815260200190565b6020808252601390820152721858d8dbdd5b9d08189b1858dadb1a5cdd1959606a1b604082015260600190565b60208082526018908201527f696e73756666696369656e74206c6f636b20616d6f756e740000000000000000604082015260600190565b6020808252601a908201527f696e73756666696369656e74206c6f636b206475726174696f6e00000000000060408201526060019056fea264697066735822122026dcf7a6136282e0ea69292b1f3e8089dc732f360805df1d27428feea21558f764736f6c63430007060033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80637edadc0414610030575b600080fd5b61005c6004803603604081101561004657600080fd5b506001600160a01b03813516906020013561005e565b005b6100666100e5565b6040805163018ee9b760e01b81523360048201526024810183905290516001600160a01b0384169163018ee9b79160448083019260209291908290030181600087803b1580156100b557600080fd5b505af11580156100c9573d6000803e3d6000fd5b505050506040513d60208110156100df57600080fd5b50505050565b60405163cbf9fe5f60e01b815260009073e4c09928d834cd58d233cd77b5af3545484b49689063cbf9fe5f9061011f9033906004016102d6565b604080518083038186803b15801561013657600080fd5b505afa15801561014a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016e919061027f565b9050600061017a61025b565b33600090815260028201602052604090205490915060ff16156101b85760405162461bcd60e51b81526004016101af906102ea565b60405180910390fd5b33600090815260018201602052604090205460ff16806101e0575080546001600160801b0316155b156101ec575050610259565b805482516001600160801b039182169116101561021b5760405162461bcd60e51b81526004016101af90610317565b805460208301516001600160801b03600160801b90920491909116420111156102565760405162461bcd60e51b81526004016101af9061034e565b50505b565b7f7b3d7c6d072f5ba80c1b8069e5afa5580d5083ebf8116656029468cd718daac790565b600060408284031215610290578081fd5b6040516040810181811067ffffffffffffffff821117156102ad57fe5b6040528251600f81900b81146102c1578283fd5b81526020928301519281019290925250919050565b6001600160a01b0391909116815260200190565b6020808252601390820152721858d8dbdd5b9d08189b1858dadb1a5cdd1959606a1b604082015260600190565b60208082526018908201527f696e73756666696369656e74206c6f636b20616d6f756e740000000000000000604082015260600190565b6020808252601a908201527f696e73756666696369656e74206c6f636b206475726174696f6e00000000000060408201526060019056fea264697066735822122026dcf7a6136282e0ea69292b1f3e8089dc732f360805df1d27428feea21558f764736f6c63430007060033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.