Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 464 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Execute Unlocks | 21440267 | 24 hrs ago | IN | 0 ETH | 0.00193894 | ||||
Kick | 21419324 | 3 days ago | IN | 0 ETH | 0.00240899 | ||||
Kick | 21418744 | 4 days ago | IN | 0 ETH | 0.0016389 | ||||
Execute Availabl... | 21406078 | 5 days ago | IN | 0 ETH | 0.00090936 | ||||
Kick | 21393861 | 7 days ago | IN | 0 ETH | 0.00240014 | ||||
Kick | 21377080 | 9 days ago | IN | 0 ETH | 0.00203089 | ||||
Kick | 21377072 | 9 days ago | IN | 0 ETH | 0.00646395 | ||||
Kick | 21376850 | 9 days ago | IN | 0 ETH | 0.00220648 | ||||
Kick | 21364279 | 11 days ago | IN | 0 ETH | 0.00184309 | ||||
Relock Multiple | 21364256 | 11 days ago | IN | 0 ETH | 0.00128866 | ||||
Kick | 21364167 | 11 days ago | IN | 0 ETH | 0.0016514 | ||||
Execute Unlocks | 21353646 | 13 days ago | IN | 0 ETH | 0.00153251 | ||||
Relock Multiple | 21351408 | 13 days ago | IN | 0 ETH | 0.00196552 | ||||
Lock For | 21320988 | 17 days ago | IN | 0 ETH | 0.00431891 | ||||
Relock Multiple | 21303145 | 20 days ago | IN | 0 ETH | 0.00267854 | ||||
Lock For | 21303142 | 20 days ago | IN | 0 ETH | 0.00263979 | ||||
Relock Multiple | 21296517 | 21 days ago | IN | 0 ETH | 0.00144337 | ||||
Lock For | 21296513 | 21 days ago | IN | 0 ETH | 0.00163884 | ||||
Relock Multiple | 21284032 | 22 days ago | IN | 0 ETH | 0.00158865 | ||||
Relock Multiple | 21284027 | 22 days ago | IN | 0 ETH | 0.00139233 | ||||
Lock For | 21284022 | 22 days ago | IN | 0 ETH | 0.00185076 | ||||
Lock For | 21278115 | 23 days ago | IN | 0 ETH | 0.00163364 | ||||
Relock Multiple | 21272676 | 24 days ago | IN | 0 ETH | 0.00441859 | ||||
Lock For | 21258679 | 26 days ago | IN | 0 ETH | 0.00327495 | ||||
Lock For | 21232771 | 30 days ago | IN | 0 ETH | 0.00193428 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
CNCLockerV3
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "SafeERC20.sol"; import "IERC20.sol"; import "Ownable.sol"; import "ScaledMath.sol"; import "ICNCLockerV3.sol"; import "ICNCToken.sol"; import "ICNCVoteLocker.sol"; import "IController.sol"; contract CNCLockerV3 is ICNCLockerV3, Ownable { using SafeERC20 for ICNCToken; using SafeERC20 for IERC20; using ScaledMath for uint256; using ScaledMath for uint128; using MerkleProof for MerkleProof.Proof; uint128 internal constant _MIN_LOCK_AMOUNT = 10e18; uint128 internal constant _MAX_LOCKS = 10; uint128 internal constant _MIN_LOCK_TIME = 120 days; uint128 internal constant _MAX_LOCK_TIME = 240 days; uint128 internal constant _GRACE_PERIOD = 28 days; uint128 internal constant _MIN_BOOST = 1e18; uint128 internal constant _MAX_BOOST = 1.5e18; uint128 internal constant _KICK_PENALTY = 1e17; uint256 internal constant _MAX_KICK_PENALTY_AMOUNT = 1000e18; uint128 constant _AIRDROP_DURATION = 182 days; uint256 internal constant _MIN_AIRDROP_BOOST = 1e18; uint256 internal constant _MAX_AIRDROP_BOOST = 3.5e18; ICNCToken public immutable cncToken; // Boost data mapping(address => uint256) public lockedBalance; mapping(address => uint256) public lockedBoosted; mapping(address => VoteLock[]) public voteLocks; mapping(address => uint256) internal _airdroppedBoost; mapping(address => bool) public override claimedAirdrop; uint64 internal _nextId; uint256 public immutable airdropEndTime; bytes32 public immutable merkleRoot; uint256 public totalLocked; uint256 public totalBoosted; bool public isShutdown; // Fee data IERC20 public immutable crv; IERC20 public immutable cvx; uint256 public accruedFeesIntegralCrv; uint256 public accruedFeesIntegralCvx; mapping(address => uint256) public perAccountAccruedCrv; mapping(address => uint256) public perAccountFeesCrv; mapping(address => uint256) public perAccountAccruedCvx; mapping(address => uint256) public perAccountFeesCvx; address public immutable treasury; IController public immutable controller; constructor( address _controller, address _cncToken, address _treasury, address _crv, address _cvx, bytes32 _merkleRoot ) Ownable() { controller = IController(_controller); cncToken = ICNCToken(_cncToken); treasury = _treasury; crv = IERC20(_crv); cvx = IERC20(_cvx); airdropEndTime = block.timestamp + _AIRDROP_DURATION; merkleRoot = _merkleRoot; } function lock(uint256 amount, uint64 lockTime) external override { lock(amount, lockTime, false); } /// @notice Lock an amount of CNC for vlCNC. /// @param amount Amount of CNC to lock. /// @param lockTime Duration of the lock. /// @param relock_ `True` if this is a relock of an existing lock. function lock(uint256 amount, uint64 lockTime, bool relock_) public override { lockFor(amount, lockTime, relock_, msg.sender); } /// @notice Lock an amount of CNC for vlCNC. /// @param amount Amount of CNC to lock. /// @param lockTime Duration of the lock. /// @param relock_ `True` if this is a relock of all existing locks. /// @param account The account to receive the vlCNC. function lockFor( uint256 amount, uint64 lockTime, bool relock_, address account ) public override { require(!isShutdown, "locker suspended"); require(amount >= _MIN_LOCK_AMOUNT, "amount too small"); require((_MIN_LOCK_TIME <= lockTime) && (lockTime <= _MAX_LOCK_TIME), "lock time invalid"); require(!relock_ || msg.sender == account, "relock only for self"); require(voteLocks[account].length < _MAX_LOCKS, "too many locks"); _feeCheckpoint(account); cncToken.safeTransferFrom(msg.sender, address(this), amount); uint128 boost = computeBoost(lockTime); uint256 airdropBoost_ = airdropBoost(msg.sender); if (airdropBoost_ > 1e18) { claimedAirdrop[msg.sender] = true; boost = boost.mulDownUint128(uint128(airdropBoost_)); delete _airdroppedBoost[msg.sender]; } uint64 unlockTime = uint64(block.timestamp) + lockTime; uint256 boostedAmount; if (relock_) { uint256 length = voteLocks[account].length; for (uint256 i; i < length; i++) { require( voteLocks[account][i].unlockTime < unlockTime, "cannot move the unlock time up" ); } delete voteLocks[account]; totalBoosted -= lockedBoosted[account]; lockedBoosted[account] = 0; _addVoteLock(account, lockedBalance[account] + amount, unlockTime, boost); boostedAmount = (lockedBalance[account] + amount).mulDown(uint256(boost)); } else { _addVoteLock(account, amount, unlockTime, boost); boostedAmount = amount.mulDown(boost); } totalLocked += amount; totalBoosted += boostedAmount; lockedBalance[account] += amount; lockedBoosted[account] += boostedAmount; emit Locked(account, amount, unlockTime, relock_); } /// @notice Process all expired locks of msg.sender and withdraw unlocked CNC. function executeAvailableUnlocks() external override returns (uint256) { return executeAvailableUnlocksFor(msg.sender); } /// @notice Process all expired locks of msg.sender and withdraw unlocked CNC to `dst`. function executeAvailableUnlocksFor(address dst) public override returns (uint256) { require(dst != address(0), "invalid destination"); _feeCheckpoint(msg.sender); uint256 sumUnlockable; uint256 sumBoosted; VoteLock[] storage _pending = voteLocks[msg.sender]; uint256 i = _pending.length; while (i > 0) { i = i - 1; if (isShutdown || _pending[i].unlockTime <= block.timestamp) { sumUnlockable += _pending[i].amount; sumBoosted += _pending[i].amount.mulDown(_pending[i].boost); _pending[i] = _pending[_pending.length - 1]; _pending.pop(); } } totalLocked -= sumUnlockable; totalBoosted -= sumBoosted; lockedBalance[msg.sender] -= sumUnlockable; lockedBoosted[msg.sender] -= sumBoosted; cncToken.safeTransfer(dst, sumUnlockable); emit UnlockExecuted(msg.sender, sumUnlockable); return sumUnlockable; } /// @notice Process specified locks of msg.sender and withdraw unlocked CNC to `dst`. /// @param dst Destination address to receive unlocked CNC. /// @param lockIds Array of lock IDs to process. /// @return unlocked Amount of CNC unlocked. function executeUnlocks( address dst, uint64[] calldata lockIds ) public override returns (uint256) { _feeCheckpoint(msg.sender); uint256 sumUnlockable; uint256 sumBoosted; VoteLock[] storage _pending = voteLocks[msg.sender]; for (uint256 idIndex; idIndex < lockIds.length; idIndex++) { uint256 index = _getLockIndexById(msg.sender, lockIds[idIndex]); require( isShutdown || _pending[index].unlockTime <= block.timestamp, "lock not expired" ); sumUnlockable += _pending[index].amount; sumBoosted += _pending[index].amount.mulDown(_pending[index].boost); _pending[index] = _pending[_pending.length - 1]; _pending.pop(); } totalLocked -= sumUnlockable; totalBoosted -= sumBoosted; lockedBalance[msg.sender] -= sumUnlockable; lockedBoosted[msg.sender] -= sumBoosted; cncToken.safeTransfer(dst, sumUnlockable); emit UnlockExecuted(msg.sender, sumUnlockable); return sumUnlockable; } /// @notice Get unlocked CNC balance for an address /// @param user Address to get unlocked CNC balance for /// @return Unlocked CNC balance function unlockableBalance(address user) public view override returns (uint256) { uint256 sumUnlockable = 0; VoteLock[] storage _pending = voteLocks[user]; uint256 length = _pending.length; for (uint256 i; i < length; i++) { if (_pending[i].unlockTime <= uint128(block.timestamp)) { sumUnlockable += _pending[i].amount; } } return sumUnlockable; } /// @notice Get unlocked boosted CNC balance for an address /// @param user Address to get unlocked boosted CNC balance for /// @return Unlocked boosted CNC balance function unlockableBalanceBoosted(address user) public view override returns (uint256) { uint256 sumUnlockable = 0; VoteLock[] storage _pending = voteLocks[user]; uint256 length = _pending.length; for (uint256 i; i < length; i++) { if (_pending[i].unlockTime <= uint128(block.timestamp)) { sumUnlockable += _pending[i].amount.mulDown(_pending[i].boost); } } return sumUnlockable; } function shutDown() external override onlyOwner { require(!isShutdown, "locker already suspended"); isShutdown = true; emit Shutdown(); } function recoverToken(address token) external override { require( token != address(cncToken) && token != address(crv) && token != address(cvx), "cannot withdraw token" ); IERC20 _token = IERC20(token); _token.safeTransfer(treasury, _token.balanceOf(address(this))); emit TokenRecovered(token); } /// @notice Relock a specific lock /// @dev Users locking CNC can create multiple locks therefore individual locks can be relocked separately. /// @param lockId Id of the lock to relock. /// @param lockTime Duration for which the locks's CNC amount should be relocked for. function relock(uint64 lockId, uint64 lockTime) external override { require(!isShutdown, "locker suspended"); require((_MIN_LOCK_TIME <= lockTime) && (lockTime <= _MAX_LOCK_TIME), "lock time invalid"); _feeCheckpoint(msg.sender); _relock(lockId, lockTime); } /// @notice Relock specified locks /// @param lockIds Ids of the locks to relock. /// @param lockTime Duration for which the locks's CNC amount should be relocked for. function relockMultiple(uint64[] calldata lockIds, uint64 lockTime) external override { require(!isShutdown, "locker suspended"); require((_MIN_LOCK_TIME <= lockTime) && (lockTime <= _MAX_LOCK_TIME), "lock time invalid"); _feeCheckpoint(msg.sender); for (uint256 i; i < lockIds.length; i++) { _relock(lockIds[i], lockTime); } } function _relock(uint64 lockId, uint64 lockTime) internal { uint256 lockIndex = _getLockIndexById(msg.sender, lockId); uint128 boost = computeBoost(lockTime); uint64 unlockTime = uint64(block.timestamp) + lockTime; VoteLock[] storage locks = voteLocks[msg.sender]; require(locks[lockIndex].unlockTime < unlockTime, "cannot move the unlock time up"); uint256 amount = locks[lockIndex].amount; uint256 previousBoostedAmount = locks[lockIndex].amount.mulDown(locks[lockIndex].boost); locks[lockIndex] = locks[locks.length - 1]; locks.pop(); _addVoteLock(msg.sender, amount, unlockTime, boost); uint256 boostedAmount = amount.mulDown(boost); totalBoosted = totalBoosted + boostedAmount - previousBoostedAmount; lockedBoosted[msg.sender] = lockedBoosted[msg.sender] + boostedAmount - previousBoostedAmount; emit Relocked(msg.sender, amount); } function relock(uint64 lockTime) external override { require(!isShutdown, "locker suspended"); require((_MIN_LOCK_TIME <= lockTime) && (lockTime <= _MAX_LOCK_TIME), "lock time invalid"); _feeCheckpoint(msg.sender); uint128 boost = computeBoost(lockTime); uint64 unlockTime = uint64(block.timestamp) + lockTime; uint256 length = voteLocks[msg.sender].length; for (uint256 i; i < length; i++) { require( voteLocks[msg.sender][i].unlockTime < unlockTime, "cannot move the unlock time up" ); } delete voteLocks[msg.sender]; totalBoosted -= lockedBoosted[msg.sender]; lockedBoosted[msg.sender] = 0; _addVoteLock(msg.sender, lockedBalance[msg.sender], unlockTime, boost); uint256 boostedAmount = lockedBalance[msg.sender].mulDown(uint256(boost)); totalBoosted += boostedAmount; lockedBoosted[msg.sender] += boostedAmount; emit Relocked(msg.sender, lockedBalance[msg.sender]); } function batchKick(LockId[] memory locks) external override { for (uint256 i; i < locks.length; i++) { kick(locks[i].user, locks[i].id); } } /// @notice Kick an expired lock function kick(address user, uint64 lockId) public override { uint256 lockIndex = _getLockIndexById(user, lockId); VoteLock[] storage _pending = voteLocks[user]; require( _pending[lockIndex].unlockTime + _GRACE_PERIOD <= uint128(block.timestamp), "cannot kick this lock" ); _feeCheckpoint(user); uint256 amount = _pending[lockIndex].amount; totalLocked -= amount; totalBoosted -= amount.mulDown(_pending[lockIndex].boost); lockedBalance[user] -= amount; lockedBoosted[user] -= amount.mulDown(_pending[lockIndex].boost); uint256 kickPenalty = amount.mulDown(_KICK_PENALTY); if (kickPenalty > _MAX_KICK_PENALTY_AMOUNT) { kickPenalty = _MAX_KICK_PENALTY_AMOUNT; } cncToken.safeTransfer(user, amount - kickPenalty); cncToken.safeTransfer(msg.sender, kickPenalty); emit KickExecuted(user, msg.sender, amount); _pending[lockIndex] = _pending[_pending.length - 1]; _pending.pop(); } function receiveFees(uint256 amountCrv, uint256 amountCvx) external override { crv.safeTransferFrom(msg.sender, address(this), amountCrv); cvx.safeTransferFrom(msg.sender, address(this), amountCvx); accruedFeesIntegralCrv += amountCrv.divDown(totalBoosted); accruedFeesIntegralCvx += amountCvx.divDown(totalBoosted); emit FeesReceived(msg.sender, amountCrv, amountCvx); } function claimFees() external override returns (uint256 crvAmount, uint256 cvxAmount) { _feeCheckpoint(msg.sender); crvAmount = perAccountFeesCrv[msg.sender]; cvxAmount = perAccountFeesCvx[msg.sender]; crv.safeTransfer(msg.sender, crvAmount); cvx.safeTransfer(msg.sender, cvxAmount); perAccountFeesCrv[msg.sender] = 0; perAccountFeesCvx[msg.sender] = 0; emit FeesClaimed(msg.sender, crvAmount, cvxAmount); } function claimAirdropBoost(uint256 amount, MerkleProof.Proof calldata proof) external override { require(block.timestamp < airdropEndTime, "airdrop ended"); require(!claimedAirdrop[msg.sender], "already claimed"); require(amount >= _MIN_AIRDROP_BOOST, "amount cannot be below 1"); require(amount <= _MAX_AIRDROP_BOOST, "amount exceeds max airdrop boost"); bytes32 node = keccak256(abi.encodePacked(msg.sender, amount)); require(proof.isValid(node, merkleRoot), "invalid proof"); _airdroppedBoost[msg.sender] = amount; emit AirdropBoostClaimed(msg.sender, amount); } function claimableFees( address account ) external view override returns (uint256 claimableCrv, uint256 claimableCvx) { uint256 boost_ = lockedBoosted[account]; claimableCrv = perAccountFeesCrv[account] + boost_.mulDown(accruedFeesIntegralCrv - perAccountAccruedCrv[account]); claimableCvx = perAccountFeesCvx[account] + boost_.mulDown(accruedFeesIntegralCvx - perAccountAccruedCvx[account]); } function balanceOf(address user) external view override returns (uint256) { return totalVoteBoost(user); } function _feeCheckpoint(address account) internal { uint256 boost_ = lockedBoosted[account]; uint256 accruedFeesIntegralCrv_ = accruedFeesIntegralCrv; uint256 accruedFeesIntegralCvx_ = accruedFeesIntegralCvx; perAccountFeesCrv[account] += boost_.mulDown( accruedFeesIntegralCrv_ - perAccountAccruedCrv[account] ); perAccountAccruedCrv[account] = accruedFeesIntegralCrv_; perAccountFeesCvx[account] += boost_.mulDown( accruedFeesIntegralCvx_ - perAccountAccruedCvx[account] ); perAccountAccruedCvx[account] = accruedFeesIntegralCvx_; // bonding stream IBonding bonding = controller.bonding(); bonding.accountCheckpoint(account); } function computeBoost(uint128 lockTime) public pure override returns (uint128) { return ((_MAX_BOOST - _MIN_BOOST).mulDownUint128( (lockTime - _MIN_LOCK_TIME).divDownUint128(_MAX_LOCK_TIME - _MIN_LOCK_TIME) ) + _MIN_BOOST); } function airdropBoost(address account) public view override returns (uint256) { if (_airdroppedBoost[account] == 0) return 1e18; return _airdroppedBoost[account]; } function totalVoteBoost(address account) public view override returns (uint256) { return totalRewardsBoost(account).mulDown(controller.lpTokenStaker().getBoost(account)); } function totalStreamBoost(address account) external view override returns (uint256) { return lockedBoosted[account]; } function totalRewardsBoost(address account) public view override returns (uint256) { return lockedBoosted[account] - unlockableBalanceBoosted(account); } function userLocks(address account) external view override returns (VoteLock[] memory) { return voteLocks[account]; } function _getLockIndexById(address user, uint64 id) internal view returns (uint256) { uint256 length_ = voteLocks[user].length; for (uint256 i; i < length_; i++) { if (voteLocks[user][i].id == id) { return i; } } revert("lock doesn't exist"); } function _addVoteLock(address user, uint256 amount, uint64 unlockTime, uint128 boost) internal { uint64 id = _nextId; voteLocks[user].push(VoteLock(amount, unlockTime, boost, id)); _nextId = id + 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "IERC20.sol"; import "IERC20Permit.sol"; import "Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; library ScaledMath { uint256 internal constant DECIMALS = 18; uint256 internal constant ONE = 10 ** DECIMALS; function mulDown(uint256 a, uint256 b) internal pure returns (uint256) { return (a * b) / ONE; } function mulDown(uint256 a, uint256 b, uint256 decimals) internal pure returns (uint256) { return (a * b) / (10 ** decimals); } function divDown(uint256 a, uint256 b) internal pure returns (uint256) { return (a * ONE) / b; } function divDown(uint256 a, uint256 b, uint256 decimals) internal pure returns (uint256) { return (a * 10 ** decimals) / b; } function divUp(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } return ((a * ONE) - 1) / b + 1; } function mulDown(int256 a, int256 b) internal pure returns (int256) { return (a * b) / int256(ONE); } function mulDownUint128(uint128 a, uint128 b) internal pure returns (uint128) { return (a * b) / uint128(ONE); } function mulDown(int256 a, int256 b, uint256 decimals) internal pure returns (int256) { return (a * b) / int256(10 ** decimals); } function divDown(int256 a, int256 b) internal pure returns (int256) { return (a * int256(ONE)) / b; } function divDownUint128(uint128 a, uint128 b) internal pure returns (uint128) { return (a * uint128(ONE)) / b; } function divDown(int256 a, int256 b, uint256 decimals) internal pure returns (int256) { return (a * int256(10 ** decimals)) / b; } function convertScale( uint256 a, uint8 fromDecimals, uint8 toDecimals ) internal pure returns (uint256) { if (fromDecimals == toDecimals) return a; if (fromDecimals > toDecimals) return downscale(a, fromDecimals, toDecimals); return upscale(a, fromDecimals, toDecimals); } function convertScale( int256 a, uint8 fromDecimals, uint8 toDecimals ) internal pure returns (int256) { if (fromDecimals == toDecimals) return a; if (fromDecimals > toDecimals) return downscale(a, fromDecimals, toDecimals); return upscale(a, fromDecimals, toDecimals); } function upscale( uint256 a, uint8 fromDecimals, uint8 toDecimals ) internal pure returns (uint256) { return a * (10 ** (toDecimals - fromDecimals)); } function downscale( uint256 a, uint8 fromDecimals, uint8 toDecimals ) internal pure returns (uint256) { return a / (10 ** (fromDecimals - toDecimals)); } function upscale( int256 a, uint8 fromDecimals, uint8 toDecimals ) internal pure returns (int256) { return a * int256(10 ** (toDecimals - fromDecimals)); } function downscale( int256 a, uint8 fromDecimals, uint8 toDecimals ) internal pure returns (int256) { return a / int256(10 ** (fromDecimals - toDecimals)); } function intPow(uint256 a, uint256 n) internal pure returns (uint256) { uint256 result = ONE; for (uint256 i; i < n; ) { result = mulDown(result, a); unchecked { ++i; } } return result; } function absSub(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { return a >= b ? a - b : b - a; } } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a <= b ? a : b; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "MerkleProof.sol"; import "IFeeRecipient.sol"; interface ICNCLockerV3 is IFeeRecipient { event Locked(address indexed account, uint256 amount, uint256 unlockTime, bool relocked); event UnlockExecuted(address indexed account, uint256 amount); event Relocked(address indexed account, uint256 amount); event KickExecuted(address indexed account, address indexed kicker, uint256 amount); event FeesClaimed(address indexed claimer, uint256 crvAmount, uint256 cvxAmount); event AirdropBoostClaimed(address indexed claimer, uint256 amount); event Shutdown(); event TokenRecovered(address indexed token); struct VoteLock { uint256 amount; uint64 unlockTime; uint128 boost; uint64 id; } struct LockId { address user; uint64 id; } function lock(uint256 amount, uint64 lockTime) external; function lock(uint256 amount, uint64 lockTime, bool relock) external; function lockFor(uint256 amount, uint64 lockTime, bool relock, address account) external; function relock(uint64 lockId, uint64 lockTime) external; function relock(uint64 lockTime) external; function relockMultiple(uint64[] calldata lockIds, uint64 lockTime) external; function totalBoosted() external view returns (uint256); function shutDown() external; function recoverToken(address token) external; function executeAvailableUnlocks() external returns (uint256); function executeAvailableUnlocksFor(address dst) external returns (uint256); function executeUnlocks(address dst, uint64[] calldata lockIds) external returns (uint256); function claimAirdropBoost(uint256 amount, MerkleProof.Proof calldata proof) external; // This will need to include the boosts etc. function balanceOf(address user) external view returns (uint256); function unlockableBalance(address user) external view returns (uint256); function unlockableBalanceBoosted(address user) external view returns (uint256); function kick(address user, uint64 lockId) external; function batchKick(LockId[] memory locks) external; function claimableFees( address account ) external view returns (uint256 claimableCrv, uint256 claimableCvx); function claimFees() external returns (uint256 crvAmount, uint256 cvxAmount); function computeBoost(uint128 lockTime) external view returns (uint128); function airdropBoost(address account) external view returns (uint256); function claimedAirdrop(address account) external view returns (bool); function totalVoteBoost(address account) external view returns (uint256); function totalStreamBoost(address account) external view returns (uint256); function totalRewardsBoost(address account) external view returns (uint256); function userLocks(address account) external view returns (VoteLock[] memory); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; library MerkleProof { struct Proof { uint16 nodeIndex; bytes32[] hashes; } function isValid( Proof memory proof, bytes32 node, bytes32 merkleRoot ) internal pure returns (bool) { uint256 length = proof.hashes.length; uint16 nodeIndex = proof.nodeIndex; for (uint256 i = 0; i < length; i++) { if (nodeIndex % 2 == 0) { node = keccak256(abi.encodePacked(node, proof.hashes[i])); } else { node = keccak256(abi.encodePacked(proof.hashes[i], node)); } nodeIndex /= 2; } return node == merkleRoot; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IFeeRecipient { event FeesReceived(address indexed sender, uint256 crvAmount, uint256 cvxAmount); function receiveFees(uint256 amountCrv, uint256 amountCvx) external; }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "IERC20.sol"; interface ICNCToken is IERC20 { event MinterAdded(address minter); event MinterRemoved(address minter); event InitialDistributionMinted(uint256 amount); event AirdropMinted(uint256 amount); event AMMRewardsMinted(uint256 amount); event TreasuryRewardsMinted(uint256 amount); event SeedShareMinted(uint256 amount); /// @notice adds a new minter function addMinter(address newMinter) external; /// @notice renounces the minter rights of the sender function renounceMinterRights() external; /// @notice mints the initial distribution amount to the distribution contract function mintInitialDistribution(address distribution) external; /// @notice mints the airdrop amount to the airdrop contract function mintAirdrop(address airdropHandler) external; /// @notice mints the amm rewards function mintAMMRewards(address ammGauge) external; /// @notice mints `amount` to `account` function mint(address account, uint256 amount) external returns (uint256); /// @notice returns a list of all authorized minters function listMinters() external view returns (address[] memory); /// @notice returns the ratio of inflation already minted function inflationMintedRatio() external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface ICNCVoteLocker { event Locked(address indexed account, uint256 amount, uint256 unlockTime, bool relocked); event UnlockExecuted(address indexed account, uint256 amount); function lock(uint256 amount) external; function lock(uint256 amount, bool relock) external; function shutDown() external; function recoverToken(address token) external; function executeAvailableUnlocks() external returns (uint256); function balanceOf(address user) external view returns (uint256); function unlockableBalance(address user) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "IConicPoolWeightManagement.sol"; import "IConicPool.sol"; import "IGenericOracle.sol"; import "IInflationManager.sol"; import "ILpTokenStaker.sol"; import "IBonding.sol"; import "IPoolAdapter.sol"; import "IFeeRecipient.sol"; import "ICurveRegistryCache.sol"; interface IController { event PoolAdded(address indexed pool); event PoolRemoved(address indexed pool); event PoolShutdown(address indexed pool); event ConvexBoosterSet(address convexBooster); event CurveHandlerSet(address curveHandler); event ConvexHandlerSet(address convexHandler); event CurveRegistryCacheSet(address curveRegistryCache); event InflationManagerSet(address inflationManager); event BondingSet(address bonding); event FeeRecipientSet(address feeRecipient); event PriceOracleSet(address priceOracle); event WeightUpdateMinDelaySet(uint256 weightUpdateMinDelay); event PauseManagerSet(address indexed manager, bool isManager); event MultiDepositsWithdrawsWhitelistSet(address pool, bool allowed); event MinimumTaintedTransferAmountSet(address indexed token, uint256 amount); event DefaultPoolAdapterSet(address poolAdapter); event CustomPoolAdapterSet(address indexed pool, address poolAdapter); struct WeightUpdate { address conicPoolAddress; IConicPoolWeightManagement.PoolWeight[] weights; } function initialize(address _lpTokenStaker) external; // inflation manager function inflationManager() external view returns (IInflationManager); function setInflationManager(address manager) external; // views function curveRegistryCache() external view returns (ICurveRegistryCache); // pool adapter function poolAdapterFor(address pool) external view returns (IPoolAdapter); function defaultPoolAdapter() external view returns (IPoolAdapter); function setDefaultPoolAdapter(address poolAdapter) external; function setCustomPoolAdapter(address pool, address poolAdapter) external; /// lp token staker function switchLpTokenStaker(address _lpTokenStaker) external; function lpTokenStaker() external view returns (ILpTokenStaker); // bonding function bonding() external view returns (IBonding); function setBonding(address _bonding) external; // fees function feeRecipient() external view returns (IFeeRecipient); function setFeeRecipient(address _feeRecipient) external; // oracle function priceOracle() external view returns (IGenericOracle); function setPriceOracle(address oracle) external; // pool functions function listPools() external view returns (address[] memory); function listActivePools() external view returns (address[] memory); function isPool(address poolAddress) external view returns (bool); function isActivePool(address poolAddress) external view returns (bool); function addPool(address poolAddress) external; function shutdownPool(address poolAddress) external; function removePool(address poolAddress) external; function cncToken() external view returns (address); function lastWeightUpdate(address poolAddress) external view returns (uint256); function updateWeights(WeightUpdate memory update) external; function updateAllWeights(WeightUpdate[] memory weights) external; // handler functions function convexBooster() external view returns (address); function curveHandler() external view returns (address); function convexHandler() external view returns (address); function setConvexBooster(address _convexBooster) external; function setCurveHandler(address _curveHandler) external; function setConvexHandler(address _convexHandler) external; function setCurveRegistryCache(address curveRegistryCache_) external; function setWeightUpdateMinDelay(uint256 delay) external; function isPauseManager(address account) external view returns (bool); function listPauseManagers() external view returns (address[] memory); function setPauseManager(address account, bool isManager) external; // deposit/withdrawal whitelist function isAllowedMultipleDepositsWithdraws(address poolAddress) external view returns (bool); function setAllowedMultipleDepositsWithdraws(address account, bool allowed) external; function getMultipleDepositsWithdrawsWhitelist() external view returns (address[] memory); // tainted transfer amount function setMinimumTaintedTransferAmount(address token, uint256 amount) external; function getMinimumTaintedTransferAmount(address token) external view returns (uint256); // constants function MAX_WEIGHT_UPDATE_MIN_DELAY() external view returns (uint256); function MIN_WEIGHT_UPDATE_MIN_DELAY() external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IConicPoolWeightManagement { struct PoolWeight { address poolAddress; uint256 weight; } function addPool(address pool) external; function removePool(address pool) external; function updateWeights(PoolWeight[] memory poolWeights) external; function handleDepeggedCurvePool(address curvePool_) external; function handleInvalidConvexPid(address pool) external returns (uint256); function allPools() external view returns (address[] memory); function poolsCount() external view returns (uint256); function getPoolAtIndex(uint256 _index) external view returns (address); function getWeight(address curvePool) external view returns (uint256); function getWeights() external view returns (PoolWeight[] memory); function isRegisteredPool(address _pool) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "ILpToken.sol"; import "IRewardManager.sol"; import "IOracle.sol"; import "IController.sol"; import "IPausable.sol"; import "IConicPoolWeightManagement.sol"; interface IConicPool is IConicPoolWeightManagement, IPausable { event Deposit( address indexed sender, address indexed receiver, uint256 depositedAmount, uint256 lpReceived ); event Withdraw(address indexed account, uint256 amount); event NewWeight(address indexed curvePool, uint256 newWeight); event NewMaxIdleCurveLpRatio(uint256 newRatio); event ClaimedRewards(uint256 claimedCrv, uint256 claimedCvx); event HandledDepeggedCurvePool(address curvePool_); event HandledInvalidConvexPid(address curvePool_, uint256 pid_); event CurvePoolAdded(address curvePool_); event CurvePoolRemoved(address curvePool_); event Shutdown(); event DepegThresholdUpdated(uint256 newThreshold); event MaxDeviationUpdated(uint256 newMaxDeviation); event RebalancingRewardsEnabledSet(bool enabled); event EmergencyRebalancingRewardFactorUpdated(uint256 factor); struct PoolWithAmount { address poolAddress; uint256 amount; } function underlying() external view returns (IERC20Metadata); function lpToken() external view returns (ILpToken); function rewardManager() external view returns (IRewardManager); function depegThreshold() external view returns (uint256); function maxIdleCurveLpRatio() external view returns (uint256); function setMaxIdleCurveLpRatio(uint256 value) external; function setMaxDeviation(uint256 maxDeviation_) external; function updateDepegThreshold(uint256 value) external; function depositFor( address _account, uint256 _amount, uint256 _minLpReceived, bool stake ) external returns (uint256); function deposit(uint256 _amount, uint256 _minLpReceived) external returns (uint256); function deposit( uint256 _amount, uint256 _minLpReceived, bool stake ) external returns (uint256); function exchangeRate() external view returns (uint256); function usdExchangeRate() external view returns (uint256); function unstakeAndWithdraw(uint256 _amount, uint256 _minAmount) external returns (uint256); function unstakeAndWithdraw( uint256 _amount, uint256 _minAmount, address _to ) external returns (uint256); function withdraw(uint256 _amount, uint256 _minAmount) external returns (uint256); function withdraw(uint256 _amount, uint256 _minAmount, address _to) external returns (uint256); function getAllocatedUnderlying() external view returns (PoolWithAmount[] memory); function rebalancingRewardActive() external view returns (bool); function totalDeviationAfterWeightUpdate() external view returns (uint256); function computeTotalDeviation() external view returns (uint256); /// @notice returns the total amount of funds held by this pool in terms of underlying function totalUnderlying() external view returns (uint256); function getTotalAndPerPoolUnderlying() external view returns ( uint256 totalUnderlying_, uint256 totalAllocated_, uint256[] memory perPoolUnderlying_ ); /// @notice same as `totalUnderlying` but returns a cached version /// that might be slightly outdated if oracle prices have changed /// @dev this is useful in cases where we want to reduce gas usage and do /// not need a precise value function cachedTotalUnderlying() external view returns (uint256); function updateRewardSpendingApproval(address token, bool approved) external; function shutdownPool() external; function isShutdown() external view returns (bool); function isBalanced() external view returns (bool); function rebalancingRewardsEnabled() external view returns (bool); function setRebalancingRewardsEnabled(bool enabled) external; function getAllUnderlyingCoins() external view returns (address[] memory result); function rebalancingRewardsFactor() external view returns (uint256); function rebalancingRewardsActivatedAt() external view returns (uint64); function getWeights() external view returns (PoolWeight[] memory); function runSanityChecks() external; }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "IERC20Metadata.sol"; interface ILpToken is IERC20Metadata { function minter() external view returns (address); function mint(address account, uint256 amount, address ubo) external returns (uint256); function burn(address _owner, uint256 _amount, address ubo) external returns (uint256); function taint(address from, address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IRewardManager { event ClaimedRewards(uint256 claimedCrv, uint256 claimedCvx); event SoldRewardTokens(uint256 targetTokenReceived); event ExtraRewardAdded(address reward); event ExtraRewardRemoved(address reward); event ExtraRewardsCurvePoolSet(address extraReward, address curvePool); event FeesSet(uint256 feePercentage); event FeesEnabled(uint256 feePercentage); event EarningsClaimed( address indexed claimedBy, uint256 cncEarned, uint256 crvEarned, uint256 cvxEarned ); function accountCheckpoint(address account) external; function poolCheckpoint() external returns (bool); function addExtraReward(address reward) external returns (bool); function addBatchExtraRewards(address[] memory rewards) external; function conicPool() external view returns (address); function setFeePercentage(uint256 _feePercentage) external; function claimableRewards( address account ) external view returns (uint256 cncRewards, uint256 crvRewards, uint256 cvxRewards); function claimEarnings() external returns (uint256, uint256, uint256); function claimPoolEarningsAndSellRewardTokens() external; function feePercentage() external view returns (uint256); function feesEnabled() external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IOracle { event TokenUpdated(address indexed token, address feed, uint256 maxDelay, bool isEthPrice); /// @notice returns the price in USD of symbol. function getUSDPrice(address token) external view returns (uint256); /// @notice returns if the given token is supported for pricing. function isTokenSupported(address token) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "Ownable.sol"; import "IController.sol"; interface IPausable { event Paused(uint256 pausedUntil); event PauseDurationSet(uint256 pauseDuration); function controller() external view returns (IController); function pausedUntil() external view returns (uint256); function pauseDuration() external view returns (uint256); function isPaused() external view returns (bool); function setPauseDuration(uint256 _pauseDuration) external; function pause() external; }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "IOracle.sol"; interface IGenericOracle is IOracle { /// @notice returns the oracle to be used to price `token` function getOracle(address token) external view returns (IOracle); /// @notice converts the price of an LP token to the given underlying function curveLpToUnderlying( address curveLpToken, address underlying, uint256 curveLpAmount ) external view returns (uint256); /// @notice same as above but avoids fetching the underlying price again function curveLpToUnderlying( address curveLpToken, address underlying, uint256 curveLpAmount, uint256 underlyingPrice ) external view returns (uint256); /// @notice converts the price an underlying asset to a given Curve LP token function underlyingToCurveLp( address underlying, address curveLpToken, uint256 underlyingAmount ) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IInflationManager { event TokensClaimed(address indexed pool, uint256 cncAmount); event RebalancingRewardHandlerAdded(address indexed pool, address indexed handler); event RebalancingRewardHandlerRemoved(address indexed pool, address indexed handler); event PoolWeightsUpdated(); function executeInflationRateUpdate() external; function updatePoolWeights() external; /// @notice returns the weights of the Conic pools to know how much inflation /// each of them will receive, as well as the total amount of USD value in all the pools function computePoolWeights() external view returns (address[] memory _pools, uint256[] memory poolWeights, uint256 totalUSDValue); function computePoolWeight( address pool ) external view returns (uint256 poolWeight, uint256 totalUSDValue); function currentInflationRate() external view returns (uint256); function getCurrentPoolInflationRate(address pool) external view returns (uint256); function handleRebalancingRewards( address account, uint256 deviationBefore, uint256 deviationAfter ) external; function addPoolRebalancingRewardHandler( address poolAddress, address rebalancingRewardHandler ) external; function removePoolRebalancingRewardHandler( address poolAddress, address rebalancingRewardHandler ) external; function rebalancingRewardHandlers( address poolAddress ) external view returns (address[] memory); function hasPoolRebalancingRewardHandler( address poolAddress, address handler ) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface ILpTokenStaker { event LpTokenStaked(address indexed account, uint256 amount); event LpTokenUnstaked(address indexed account, uint256 amount); event TokensClaimed(address indexed pool, uint256 cncAmount); event Shutdown(); function stake(uint256 amount, address conicPool) external; function unstake(uint256 amount, address conicPool) external; function stakeFor(uint256 amount, address conicPool, address account) external; function unstakeFor(uint256 amount, address conicPool, address account) external; function unstakeFrom(uint256 amount, address account) external; function getUserBalanceForPool( address conicPool, address account ) external view returns (uint256); function getBalanceForPool(address conicPool) external view returns (uint256); function updateBoost(address user) external; function claimCNCRewardsForPool(address pool) external; function claimableCnc(address pool) external view returns (uint256); function checkpoint(address pool) external returns (uint256); function shutdown() external; function getBoost(address user) external view returns (uint256); function isShutdown() external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IBonding { event CncStartPriceSet(uint256 startPrice); event PriceIncreaseFactorSet(uint256 factor); event MinBondingAmountSet(uint256 amount); event Bonded( address indexed account, address indexed recipient, uint256 lpTokenAmount, uint256 cncReceived, uint256 lockTime ); event DebtPoolSet(address indexed pool); event DebtPoolFeesClaimed(uint256 crvAmount, uint256 cvxAmount, uint256 cncAmount); event StreamClaimed(address indexed account, uint256 amount); event BondingStarted(uint256 amount, uint256 epochs); event RemainingCNCRecovered(uint256 amount); function startBonding() external; function setCncStartPrice(uint256 _cncStartPrice) external; function setCncPriceIncreaseFactor(uint256 _priceIncreaseFactor) external; function setMinBondingAmount(uint256 _minBondingAmount) external; function setDebtPool(address _debtPool) external; function bondCncCrvUsd( uint256 lpTokenAmount, uint256 minCncReceived, uint64 cncLockTime ) external returns (uint256); function recoverRemainingCNC() external; function claimStream() external; function claimFeesForDebtPool() external; function streamCheckpoint() external; function accountCheckpoint(address account) external; function computeCurrentCncBondPrice() external view returns (uint256); function cncAvailable() external view returns (uint256); function cncBondPrice() external view returns (uint256); function bondCncCrvUsdFor( uint256 lpTokenAmount, uint256 minCncReceived, uint64 cncLockTime, address recipient ) external returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IPoolAdapter { /// @notice This is to set which LP token price the value computation should use /// `Latest` uses a freshly computed price /// `Cached` uses the price in cache /// `Minimum` uses the minimum of these two enum PriceMode { Latest, Cached, Minimum } /// @notice Deposit `underlyingAmount` of `underlying` into `pool` /// @dev This function should be written with the assumption that it will be delegate-called into function deposit(address pool, address underlying, uint256 underlyingAmount) external; /// @notice Withdraw `underlyingAmount` of `underlying` from `pool` /// @dev This function should be written with the assumption that it will be delegate-called into function withdraw(address pool, address underlying, uint256 underlyingAmount) external; /// @notice Returns the amount of of assets that `conicPool` holds in `pool`, in terms of USD function computePoolValueInUSD( address conicPool, address pool ) external view returns (uint256 usdAmount); /// @notice Updates the price caches of the given pools function updatePriceCache(address pool) external; /// @notice Returns the amount of of assets that `conicPool` holds in `pool`, in terms of USD /// using the given price mode function computePoolValueInUSD( address conicPool, address pool, PriceMode priceMode ) external view returns (uint256 usdAmount); /// @notice Returns the amount of of assets that `conicPool` holds in `pool`, in terms of underlying function computePoolValueInUnderlying( address conicPool, address pool, address underlying, uint256 underlyingPrice ) external view returns (uint256 underlyingAmount); /// @notice Returns the amount of of assets that `conicPool` holds in `pool`, in terms of underlying /// using the given price mode function computePoolValueInUnderlying( address conicPool, address pool, address underlying, uint256 underlyingPrice, PriceMode priceMode ) external view returns (uint256 underlyingAmount); /// @notice Claim earnings of `conicPool` from `pool` function claimEarnings(address conicPool, address pool) external; /// @notice Returns the LP token of a given `pool` function lpToken(address pool) external view returns (address); /// @notice Returns true if `pool` supports `asset` function supportsAsset(address pool, address asset) external view returns (bool); /// @notice Returns the amount of CRV earned by `pool` on Convex function getCRVEarnedOnConvex( address account, address curvePool ) external view returns (uint256); /// @notice Executes a sanity check, e.g. checking for reentrancy function executeSanityCheck(address pool) external; /// @notice returns all the underlying coins of the pool function getAllUnderlyingCoins(address pool) external view returns (address[] memory); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "IBooster.sol"; import "CurvePoolUtils.sol"; interface ICurveRegistryCache { event PoolInitialized(address indexed pool, uint256 indexed pid); function BOOSTER() external view returns (IBooster); function initPool(address pool_) external; function initPool(address pool_, uint256 pid_) external; function lpToken(address pool_) external view returns (address); function assetType(address pool_) external view returns (CurvePoolUtils.AssetType); function isRegistered(address pool_) external view returns (bool); function hasCoinDirectly(address pool_, address coin_) external view returns (bool); function hasCoinAnywhere(address pool_, address coin_) external view returns (bool); function basePool(address pool_) external view returns (address); function coinIndex(address pool_, address coin_) external view returns (int128); function nCoins(address pool_) external view returns (uint256); function coinIndices( address pool_, address from_, address to_ ) external view returns (int128, int128, bool); function decimals(address pool_) external view returns (uint256[] memory); function interfaceVersion(address pool_) external view returns (uint256); function poolFromLpToken(address lpToken_) external view returns (address); function coins(address pool_) external view returns (address[] memory); function getPid(address _pool) external view returns (uint256); function getRewardPool(address _pool) external view returns (address); function isShutdownPid(uint256 pid_) external view returns (bool); /// @notice this returns the underlying coins of a pool, including the underlying of the base pool /// if the given pool is a meta pool /// This does not return the LP token of the base pool as an underlying /// e.g. if the pool is 3CrvFrax, this will return FRAX, DAI, USDC, USDT function getAllUnderlyingCoins(address pool) external view returns (address[] memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17; interface IBooster { function poolInfo( uint256 pid ) external view returns ( address lpToken, address token, address gauge, address crvRewards, address stash, bool shutdown ); function poolLength() external view returns (uint256); function deposit(uint256 _pid, uint256 _amount, bool _stake) external returns (bool); function withdraw(uint256 _pid, uint256 _amount) external returns (bool); function withdrawAll(uint256 _pid) external returns (bool); function depositAll(uint256 _pid, bool _stake) external returns (bool); function earmarkRewards(uint256 _pid) external returns (bool); function isShutdown() external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "ICurvePoolV2.sol"; import "ICurvePoolV1.sol"; import "ScaledMath.sol"; library CurvePoolUtils { using ScaledMath for uint256; error NotWithinThreshold(address pool, uint256 assetA, uint256 assetB); /// @dev by default, allow for 30 bps deviation regardless of pool fees uint256 internal constant _DEFAULT_IMBALANCE_BUFFER = 30e14; /// @dev Curve scales the `fee` by 1e10 uint8 internal constant _CURVE_POOL_FEE_DECIMALS = 10; /// @dev allow imbalance to be buffer + 3x the fee, e.g. if fee is 3.6 bps and buffer is 30 bps, allow 40.8 bps uint256 internal constant _FEE_IMBALANCE_MULTIPLIER = 3; enum AssetType { USD, ETH, BTC, OTHER, CRYPTO } struct PoolMeta { address pool; uint256 numberOfCoins; AssetType assetType; uint256[] decimals; uint256[] prices; uint256[] imbalanceBuffers; } function ensurePoolBalanced(PoolMeta memory poolMeta) internal view { uint256 poolFee = ICurvePoolV1(poolMeta.pool).fee().convertScale( _CURVE_POOL_FEE_DECIMALS, 18 ); for (uint256 i = 0; i < poolMeta.numberOfCoins - 1; i++) { uint256 fromDecimals = poolMeta.decimals[i]; uint256 fromBalance = 10 ** fromDecimals; uint256 fromPrice = poolMeta.prices[i]; for (uint256 j = i + 1; j < poolMeta.numberOfCoins; j++) { uint256 toDecimals = poolMeta.decimals[j]; uint256 toPrice = poolMeta.prices[j]; uint256 toExpectedUnscaled = (fromBalance * fromPrice) / toPrice; uint256 toExpected = toExpectedUnscaled.convertScale( uint8(fromDecimals), uint8(toDecimals) ); uint256 toActual; if (poolMeta.assetType == AssetType.CRYPTO) { // Handling crypto pools toActual = ICurvePoolV2(poolMeta.pool).get_dy(i, j, fromBalance); } else { // Handling other pools toActual = ICurvePoolV1(poolMeta.pool).get_dy( int128(uint128(i)), int128(uint128(j)), fromBalance ); } uint256 _maxImbalanceBuffer = poolMeta.imbalanceBuffers[i].max( poolMeta.imbalanceBuffers[j] ); if (!_isWithinThreshold(toExpected, toActual, poolFee, _maxImbalanceBuffer)) revert NotWithinThreshold(poolMeta.pool, i, j); } } } function _isWithinThreshold( uint256 a, uint256 b, uint256 poolFee, uint256 imbalanceBuffer ) internal pure returns (bool) { if (imbalanceBuffer == 0) imbalanceBuffer = _DEFAULT_IMBALANCE_BUFFER; uint256 imbalanceTreshold = imbalanceBuffer + poolFee * _FEE_IMBALANCE_MULTIPLIER; if (a > b) return (a - b).divDown(a) <= imbalanceTreshold; return (b - a).divDown(b) <= imbalanceTreshold; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17; interface ICurvePoolV2 { function token() external view returns (address); function coins(uint256 i) external view returns (address); function factory() external view returns (address); function exchange( uint256 i, uint256 j, uint256 dx, uint256 min_dy, bool use_eth, address receiver ) external returns (uint256); function exchange_underlying( uint256 i, uint256 j, uint256 dx, uint256 min_dy, address receiver ) external returns (uint256); function add_liquidity( uint256[2] memory amounts, uint256 min_mint_amount, bool use_eth, address receiver ) external returns (uint256); function add_liquidity( uint256[2] memory amounts, uint256 min_mint_amount ) external returns (uint256); function add_liquidity( uint256[3] memory amounts, uint256 min_mint_amount, bool use_eth, address receiver ) external returns (uint256); function add_liquidity( uint256[3] memory amounts, uint256 min_mint_amount ) external returns (uint256); function remove_liquidity( uint256 _amount, uint256[2] memory min_amounts, bool use_eth, address receiver ) external; function remove_liquidity(uint256 _amount, uint256[2] memory min_amounts) external; function remove_liquidity( uint256 _amount, uint256[3] memory min_amounts, bool use_eth, address receiver ) external; function remove_liquidity(uint256 _amount, uint256[3] memory min_amounts) external; function remove_liquidity_one_coin( uint256 token_amount, uint256 i, uint256 min_amount, bool use_eth, address receiver ) external returns (uint256); function get_dy(uint256 i, uint256 j, uint256 dx) external view returns (uint256); function calc_token_amount(uint256[] memory amounts) external view returns (uint256); function calc_withdraw_one_coin( uint256 token_amount, uint256 i ) external view returns (uint256); function get_virtual_price() external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17; interface ICurvePoolV1 { function get_virtual_price() external view returns (uint256); function add_liquidity(uint256[8] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[7] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[6] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[5] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[4] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[3] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[2] calldata amounts, uint256 min_mint_amount) external; function remove_liquidity_imbalance( uint256[4] calldata amounts, uint256 max_burn_amount ) external; function remove_liquidity_imbalance( uint256[3] calldata amounts, uint256 max_burn_amount ) external; function remove_liquidity_imbalance( uint256[2] calldata amounts, uint256 max_burn_amount ) external; function lp_token() external view returns (address); function A_PRECISION() external view returns (uint256); function A_precise() external view returns (uint256); function remove_liquidity(uint256 _amount, uint256[3] calldata min_amounts) external; function exchange( int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external; function coins(uint256 i) external view returns (address); function balances(uint256 i) external view returns (uint256); function get_dy(int128 i, int128 j, uint256 _dx) external view returns (uint256); function calc_token_amount( uint256[4] calldata amounts, bool deposit ) external view returns (uint256); function calc_token_amount( uint256[3] calldata amounts, bool deposit ) external view returns (uint256); function calc_token_amount( uint256[2] calldata amounts, bool deposit ) external view returns (uint256); function calc_withdraw_one_coin( uint256 _token_amount, int128 i ) external view returns (uint256); function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_amount ) external; function fee() external view returns (uint256); }
{ "evmVersion": "london", "optimizer": { "enabled": true, "runs": 200 }, "libraries": { "CNCLockerV3.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"_cncToken","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_crv","type":"address"},{"internalType":"address","name":"_cvx","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AirdropBoostClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"crvAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cvxAmount","type":"uint256"}],"name":"FeesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"crvAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cvxAmount","type":"uint256"}],"name":"FeesReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"kicker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"KickExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlockTime","type":"uint256"},{"indexed":false,"internalType":"bool","name":"relocked","type":"bool"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Relocked","type":"event"},{"anonymous":false,"inputs":[],"name":"Shutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"TokenRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnlockExecuted","type":"event"},{"inputs":[],"name":"accruedFeesIntegralCrv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accruedFeesIntegralCvx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"airdropBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdropEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint64","name":"id","type":"uint64"}],"internalType":"struct ICNCLockerV3.LockId[]","name":"locks","type":"tuple[]"}],"name":"batchKick","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"uint16","name":"nodeIndex","type":"uint16"},{"internalType":"bytes32[]","name":"hashes","type":"bytes32[]"}],"internalType":"struct MerkleProof.Proof","name":"proof","type":"tuple"}],"name":"claimAirdropBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimFees","outputs":[{"internalType":"uint256","name":"crvAmount","type":"uint256"},{"internalType":"uint256","name":"cvxAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"claimableFees","outputs":[{"internalType":"uint256","name":"claimableCrv","type":"uint256"},{"internalType":"uint256","name":"claimableCvx","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimedAirdrop","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cncToken","outputs":[{"internalType":"contract ICNCToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"lockTime","type":"uint128"}],"name":"computeBoost","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crv","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvx","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"executeAvailableUnlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"}],"name":"executeAvailableUnlocksFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint64[]","name":"lockIds","type":"uint64[]"}],"name":"executeUnlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint64","name":"lockId","type":"uint64"}],"name":"kick","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"lockTime","type":"uint64"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"lockTime","type":"uint64"},{"internalType":"bool","name":"relock_","type":"bool"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"lockTime","type":"uint64"},{"internalType":"bool","name":"relock_","type":"bool"},{"internalType":"address","name":"account","type":"address"}],"name":"lockFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockedBoosted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"perAccountAccruedCrv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"perAccountAccruedCvx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"perAccountFeesCrv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"perAccountFeesCvx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountCrv","type":"uint256"},{"internalType":"uint256","name":"amountCvx","type":"uint256"}],"name":"receiveFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"recoverToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"lockId","type":"uint64"},{"internalType":"uint64","name":"lockTime","type":"uint64"}],"name":"relock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"lockTime","type":"uint64"}],"name":"relock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"lockIds","type":"uint64[]"},{"internalType":"uint64","name":"lockTime","type":"uint64"}],"name":"relockMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutDown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalBoosted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"totalRewardsBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"totalStreamBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"totalVoteBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"unlockableBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"unlockableBalanceBoosted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"userLocks","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"unlockTime","type":"uint64"},{"internalType":"uint128","name":"boost","type":"uint128"},{"internalType":"uint64","name":"id","type":"uint64"}],"internalType":"struct ICNCLockerV3.VoteLock[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"voteLocks","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"unlockTime","type":"uint64"},{"internalType":"uint128","name":"boost","type":"uint128"},{"internalType":"uint64","name":"id","type":"uint64"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101606040523480156200001257600080fd5b5060405162003f2d38038062003f2d8339810160408190526200003591620000f6565b620000403362000089565b6001600160a01b03808716610140528581166080528481166101205283811660e0528216610100526200007762eff100426200016e565b60a05260c05250620001969350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620000f157600080fd5b919050565b60008060008060008060c087890312156200011057600080fd5b6200011b87620000d9565b95506200012b60208801620000d9565b94506200013b60408801620000d9565b93506200014b60608801620000d9565b92506200015b60808801620000d9565b915060a087015190509295509295509295565b808201808211156200019057634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e051610100516101205161014051613cc5620002686000396000818161078e01528181610f3b015261297c0152600081816104b301526117d801526000818161060a01528181610dac0152818161174401526121b901526000818161052201528181610d7701528181611706015261217d0152600081816103fb0152610a180152600081816105d2015261086e0152600081816104fb01528181611423015281816116c901528181611ab501528181611ae901528181611e1e015261256f0152613cc56000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c8063715018a611610182578063a6aed923116100e9578063ddecf662116100a2578063edaf69bd1161007c578063edaf69bd14610763578063f2fde38b14610776578063f77c479114610789578063f816144e146107b057600080fd5b8063ddecf662146106db578063dfb142ae14610725578063ea312d761461073857600080fd5b8063a6aed92314610685578063bb3cac5414610698578063bf4b3e65146106ab578063bf86d690146106b3578063c5890d2d146106c0578063d294f093146106d357600080fd5b80638da5cb5b1161013b5780638da5cb5b146105f4578063923c1d611461060557806393ed9d011461062c578063984acb491461063f5780639ae697bf146106525780639be65a601461067257600080fd5b8063715018a61461055757806378f89c201461055f5780637907706f146105725780637bf500c8146105855780637e0b2492146105a5578063806019c1146105cd57600080fd5b806346e919d0116102265780635f07112f116101df5780635f07112f1461049b57806361d027b3146104ae578063631516c2146104ed578063645d28a8146104f65780636a4874a11461051d57806370a082311461054457600080fd5b806346e919d0146104305780634f348758146104435780635219c5121461045657806356891412146104695780635cad88eb146104725780635ee26ad01461047b57600080fd5b80631c91607f116102785780631c91607f1461038757806326a4c842146103a757806328a81039146103ba5780632a324607146103e35780632eb4a7ab146103f65780633efa99791461041d57600080fd5b80630259ef58146102c05780630499abd4146102e95780630b70608f1461031757806310b9e5831461032c57806311e1dc1e146103345780631b93f66d14610354575b600080fd5b6102d36102ce366004613301565b6107b9565b6040516102e0919061331e565b60405180910390f35b6103096102f7366004613301565b600c6020526000908152604090205481565b6040519081526020016102e0565b61032a610325366004613397565b61086c565b005b61032a610ad5565b610309610342366004613301565b600e6020526000908152604090205481565b610377610362366004613301565b60056020526000908152604090205460ff1681565b60405190151581526020016102e0565b610309610395366004613301565b600f6020526000908152604090205481565b61032a6103b536600461344b565b610b68565b6103096103c8366004613301565b6001600160a01b031660009081526002602052604090205490565b6103096103f1366004613301565b610c2c565b6103097f000000000000000000000000000000000000000000000000000000000000000081565b61032a61042b36600461349e565b610d26565b61030961043e366004613301565b610d36565b61032a6104513660046134ca565b610d6a565b610309610464366004613301565b610e5b565b61030960075481565b610309600a5481565b610309610489366004613301565b60026020526000908152604090205481565b61032a6104a93660046134fa565b610f04565b6104d57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102e0565b61030960085481565b6104d57f000000000000000000000000000000000000000000000000000000000000000081565b6104d57f000000000000000000000000000000000000000000000000000000000000000081565b610309610552366004613301565b610f15565b61032a610f20565b61030961056d366004613301565b610f34565b61032a61058036600461353a565b611036565b610309610593366004613301565b600d6020526000908152604090205481565b6105b86105b3366004613301565b6110b1565b604080519283526020830191909152016102e0565b6103097f000000000000000000000000000000000000000000000000000000000000000081565b6000546001600160a01b03166104d5565b6104d57f000000000000000000000000000000000000000000000000000000000000000081565b61030961063a366004613564565b61116b565b61032a61064d3660046135b8565b61148a565b610309610660366004613301565b60016020526000908152604090205481565b61032a610680366004613301565b6116c7565b61032a6106933660046135d3565b611896565b6103096106a6366004613301565b611c4a565b610309611c94565b6009546103779060ff1681565b61032a6106ce3660046135f1565b611ca4565b6105b861214b565b6106ee6106e9366004613642565b61223a565b604080519485526001600160401b0393841660208601526001600160801b03909216918401919091521660608201526080016102e0565b610309610733366004613301565b61229a565b61074b61074636600461366e565b6125d5565b6040516001600160801b0390911681526020016102e0565b61032a610771366004613728565b612646565b61032a610784366004613301565b6126a8565b6104d57f000000000000000000000000000000000000000000000000000000000000000081565b610309600b5481565b6001600160a01b0381166000908152600360209081526040808320805482518185028101850190935280835260609492939192909184015b828210156108615760008481526020908190206040805160808101825260028602909201805483526001908101546001600160401b03808216858701526001600160801b03600160401b83041693850193909352600160c01b9004909116606083015290835290920191016107f1565b505050509050919050565b7f000000000000000000000000000000000000000000000000000000000000000042106108d05760405162461bcd60e51b815260206004820152600d60248201526c185a5c991c9bdc08195b991959609a1b60448201526064015b60405180910390fd5b3360009081526005602052604090205460ff16156109225760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b60448201526064016108c7565b670de0b6b3a764000082101561097a5760405162461bcd60e51b815260206004820152601860248201527f616d6f756e742063616e6e6f742062652062656c6f772031000000000000000060448201526064016108c7565b6730927f74c9de00008211156109d25760405162461bcd60e51b815260206004820181905260248201527f616d6f756e742065786365656473206d61782061697264726f7020626f6f737460448201526064016108c7565b6040516bffffffffffffffffffffffff193360601b16602082015260348101839052600090605401604051602081830303815290604052805190602001209050610a48817f000000000000000000000000000000000000000000000000000000000000000084610a41906137e8565b9190612721565b610a845760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b60448201526064016108c7565b3360008181526004602052604090819020859055517ffb7c165a21b698d172209fd3fbb4a907042c12438cd506666064cd98e0a142aa90610ac89086815260200190565b60405180910390a2505050565b610add61281f565b60095460ff1615610b305760405162461bcd60e51b815260206004820152601860248201527f6c6f636b657220616c72656164792073757370656e646564000000000000000060448201526064016108c7565b6009805460ff191660011790556040517f4426aa1fb73e391071491fcfe21a88b5c38a0a0333a1f6e77161470439704cf890600090a1565b60095460ff1615610b8b5760405162461bcd60e51b81526004016108c79061389d565b6001600160401b038116629e340011801590610bb4575063013c68006001600160401b03821611155b610bd05760405162461bcd60e51b81526004016108c7906138c7565b610bd933612879565b60005b82811015610c2657610c14848483818110610bf957610bf96138f2565b9050602002016020810190610c0e91906135b8565b83612a4f565b80610c1e8161391e565b915050610bdc565b50505050565b6001600160a01b03811660009081526003602052604081208054829190825b81811015610d1c57426001600160801b0316838281548110610c6f57610c6f6138f2565b60009182526020909120600160029092020101546001600160401b031611610d0a57610cfd838281548110610ca657610ca66138f2565b906000526020600020906002020160010160089054906101000a90046001600160801b03166001600160801b0316848381548110610ce657610ce66138f2565b600091825260209091206002909102015490612d1e565b610d079085613937565b93505b80610d148161391e565b915050610c4b565b5091949350505050565b610d3282826000610f04565b5050565b6000610d4182610c2c565b6001600160a01b038316600090815260026020526040902054610d64919061394a565b92915050565b610d9f6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085612d47565b610dd46001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084612d47565b600854610de2908390612db2565b600a6000828254610df39190613937565b9091555050600854610e06908290612db2565b600b6000828254610e179190613937565b9091555050604080518381526020810183905233917f213e72af0d3613bd643cff3059f872c1015e6541624e37872bf95eefbaf220a8910160405180910390a25050565b6001600160a01b03811660009081526003602052604081208054829190825b81811015610d1c57426001600160801b0316838281548110610e9e57610e9e6138f2565b60009182526020909120600160029092020101546001600160401b031611610ef257828181548110610ed257610ed26138f2565b90600052602060002090600202016000015484610eef9190613937565b93505b80610efc8161391e565b915050610e7a565b610f1083838333611ca4565b505050565b6000610d6482610f34565b610f2861281f565b610f326000612dcb565b565b6000610d647f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166348439e7e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbb919061395d565b60405163067ba3d960e41b81526001600160a01b03858116600483015291909116906367ba3d9090602401602060405180830381865afa158015611003573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611027919061397a565b61103084610d36565b90612d1e565b60095460ff16156110595760405162461bcd60e51b81526004016108c79061389d565b6001600160401b038116629e340011801590611082575063013c68006001600160401b03821611155b61109e5760405162461bcd60e51b81526004016108c7906138c7565b6110a733612879565b610d328282612a4f565b6001600160a01b038116600090815260026020908152604080832054600c909252822054600a548392916110f0916110e9919061394a565b8290612d1e565b6001600160a01b0385166000908152600d60205260409020546111139190613937565b6001600160a01b0385166000908152600e6020526040902054600b54919450611140916110e9919061394a565b6001600160a01b0385166000908152600f60205260409020546111639190613937565b915050915091565b600061117633612879565b3360009081526003602052604081208190815b8581101561139c5760006111c3338989858181106111a9576111a96138f2565b90506020020160208101906111be91906135b8565b612e1b565b60095490915060ff16806112055750428382815481106111e5576111e56138f2565b60009182526020909120600160029092020101546001600160401b031611155b6112445760405162461bcd60e51b815260206004820152601060248201526f1b1bd8dac81b9bdd08195e1c1a5c995960821b60448201526064016108c7565b828181548110611256576112566138f2565b906000526020600020906002020160000154856112739190613937565b945061128a838281548110610ca657610ca66138f2565b6112949085613937565b835490945083906112a79060019061394a565b815481106112b7576112b76138f2565b90600052602060002090600202018382815481106112d7576112d76138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b03909116179055825483908061136b5761136b613993565b60008281526020812060026000199093019283020181815560010155905550806113948161391e565b915050611189565b5082600760008282546113af919061394a565b9250508190555081600860008282546113c8919061394a565b909155505033600090815260016020526040812080548592906113ec90849061394a565b9091555050336000908152600260205260408120805484929061141090849061394a565b9091555061144a90506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168885612ef6565b60405183815233907fb291e2a2847a5ad6d47409943306c6d6e8c63a9855b849701b868191e94789709060200160405180910390a2509095945050505050565b60095460ff16156114ad5760405162461bcd60e51b81526004016108c79061389d565b6001600160401b038116629e3400118015906114d6575063013c68006001600160401b03821611155b6114f25760405162461bcd60e51b81526004016108c7906138c7565b6114fb33612879565b600061150f826001600160401b03166125d5565b9050600061151d83426139a9565b336000908152600360205260408120549192505b818110156115b25733600090815260036020526040902080546001600160401b038516919083908110611566576115666138f2565b60009182526020909120600160029092020101546001600160401b0316106115a05760405162461bcd60e51b81526004016108c7906139d0565b806115aa8161391e565b915050611531565b503360009081526003602052604081206115cb916132b1565b3360009081526002602052604081205460088054919290916115ee90849061394a565b9091555050336000818152600260209081526040808320839055600190915290205461161c91908486612f26565b3360009081526001602052604081205461163f906001600160801b038616612d1e565b905080600860008282546116539190613937565b90915550503360009081526002602052604081208054839290611677908490613937565b9091555050336000818152600160209081526040918290205491519182527fe2d155d9d74decc198a9a9b4f5bddb24ee0842ee745c9ce57e3573b971e50d9d910160405180910390a25050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b03161415801561173b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614155b801561177957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614155b6117bd5760405162461bcd60e51b815260206004820152601560248201527431b0b73737ba103bb4ba34323930bb903a37b5b2b760591b60448201526064016108c7565b6040516370a0823160e01b8152306004820152819061185e907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184d919061397a565b6001600160a01b0384169190612ef6565b6040516001600160a01b038316907f17a79be10b6da9324a110f0ea6d3043db38f1eee6e2ee1dbfa7272338e39da4590600090a25050565b60006118a28383612e1b565b6001600160a01b03841660009081526003602052604090208054919250906001600160801b034216906224ea00908390859081106118e2576118e26138f2565b600091825260209091206001600290920201015461190991906001600160401b0316613a07565b6001600160801b031611156119585760405162461bcd60e51b815260206004820152601560248201527463616e6e6f74206b69636b2074686973206c6f636b60581b60448201526064016108c7565b61196184612879565b6000818381548110611975576119756138f2565b9060005260206000209060020201600001549050806007600082825461199b919061394a565b925050819055506119e28284815481106119b7576119b76138f2565b60009182526020909120600290910201600101548290600160401b90046001600160801b0316612d1e565b600860008282546119f3919061394a565b90915550506001600160a01b03851660009081526001602052604081208054839290611a2090849061394a565b92505081905550611a3c8284815481106119b7576119b76138f2565b6001600160a01b03861660009081526002602052604081208054909190611a6490849061394a565b9091555060009050611a7e8267016345785d8a0000612d1e565b9050683635c9adc5dea00000811115611a9d5750683635c9adc5dea000005b611adc86611aab838561394a565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169190612ef6565b611b106001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383612ef6565b60405182815233906001600160a01b038816907f9716d4c8630c7c1a47a462f169d1764a38687f7532baf2bd74a791afc20030e69060200160405180910390a382548390611b609060019061394a565b81548110611b7057611b706138f2565b9060005260206000209060020201838581548110611b9057611b906138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b039091161790558254839080611c2457611c24613993565b600082815260208120600260001990930192830201818155600101559055505050505050565b6001600160a01b0381166000908152600460205260408120548103611c785750670de0b6b3a7640000919050565b506001600160a01b031660009081526004602052604090205490565b6000611c9f3361229a565b905090565b60095460ff1615611cc75760405162461bcd60e51b81526004016108c79061389d565b678ac7230489e80000841015611d125760405162461bcd60e51b815260206004820152601060248201526f185b5bdd5b9d081d1bdbc81cdb585b1b60821b60448201526064016108c7565b6001600160401b038316629e340011801590611d3b575063013c68006001600160401b03841611155b611d575760405162461bcd60e51b81526004016108c7906138c7565b811580611d6c5750336001600160a01b038216145b611daf5760405162461bcd60e51b81526020600482015260146024820152733932b637b1b59037b7363c903337b91039b2b63360611b60448201526064016108c7565b6001600160a01b038116600090815260036020526040902054600a11611e085760405162461bcd60e51b815260206004820152600e60248201526d746f6f206d616e79206c6f636b7360901b60448201526064016108c7565b611e1181612879565b611e466001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333087612d47565b6000611e5a846001600160401b03166125d5565b90506000611e6733611c4a565b9050670de0b6b3a7640000811115611eb957336000908152600560205260409020805460ff19166001179055611ea66001600160801b03831682613011565b3360009081526004602052604081205591505b6000611ec586426139a9565b905060008515612040576001600160a01b038516600090815260036020526040812054905b81811015611f74576001600160a01b038716600090815260036020526040902080546001600160401b038616919083908110611f2857611f286138f2565b60009182526020909120600160029092020101546001600160401b031610611f625760405162461bcd60e51b81526004016108c7906139d0565b80611f6c8161391e565b915050611eea565b506001600160a01b0386166000908152600360205260408120611f96916132b1565b6001600160a01b0386166000908152600260205260408120546008805491929091611fc290849061394a565b90915550506001600160a01b03861660009081526002602090815260408083208390556001909152902054612005908790611ffe908c90613937565b8588612f26565b6001600160a01b038616600090815260016020526040902054612038906001600160801b03871690611030908c90613937565b915050612062565b61204c85898487612f26565b61205f886001600160801b038616612d1e565b90505b87600760008282546120749190613937565b92505081905550806008600082825461208d9190613937565b90915550506001600160a01b038516600090815260016020526040812080548a92906120ba908490613937565b90915550506001600160a01b038516600090815260026020526040812080548392906120e7908490613937565b9091555050604080518981526001600160401b03841660208201528715158183015290516001600160a01b038716917fca8d506eda84f8ed07c2908ae102299d34888ef5e19b97f56e4d6fcd1104c31e919081900360600190a25050505050505050565b60008061215733612879565b5050336000818152600d6020908152604080832054600f9092529091205490916121ac907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169084612ef6565b6121e06001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383612ef6565b336000818152600d60209081526040808320839055600f82528083209290925581518581529081018490527f1ac537f0ad67b64ac68a04587ff3a4cb6977de22eb2c37ee560897a92c6d07c7910160405180910390a29091565b6003602052816000526040600020818154811061225657600080fd5b6000918252602090912060029091020180546001909101549092506001600160401b0380821692506001600160801b03600160401b83041691600160c01b90041684565b60006001600160a01b0382166122e85760405162461bcd60e51b815260206004820152601360248201527234b73b30b634b2103232b9ba34b730ba34b7b760691b60448201526064016108c7565b6122f133612879565b33600090815260036020526040812080548291905b80156124e95761231760018261394a565b60095490915060ff1680612359575042828281548110612339576123396138f2565b60009182526020909120600160029092020101546001600160401b031611155b156124e457818181548110612370576123706138f2565b9060005260206000209060020201600001548461238d9190613937565b93506123e48282815481106123a4576123a46138f2565b906000526020600020906002020160010160089054906101000a90046001600160801b03166001600160801b0316838381548110610ce657610ce66138f2565b6123ee9084613937565b825490935082906124019060019061394a565b81548110612411576124116138f2565b9060005260206000209060020201828281548110612431576124316138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b0390911617905581548290806124c5576124c5613993565b6000828152602081206002600019909301928302018181556001015590555b612306565b83600760008282546124fb919061394a565b925050819055508260086000828254612514919061394a565b9091555050336000908152600160205260408120805486929061253890849061394a565b9091555050336000908152600260205260408120805485929061255c90849061394a565b9091555061259690506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168786612ef6565b60405184815233907fb291e2a2847a5ad6d47409943306c6d6e8c63a9855b849701b868191e94789709060200160405180910390a25091949350505050565b6000670de0b6b3a764000061263c6126136125f7629e340063013c6800613a27565b612604629e340087613a27565b6001600160801b031690613033565b61262d670de0b6b3a76400006714d1120d7b160000613a27565b6001600160801b031690613011565b610d649190613a07565b60005b8151811015610d3257612696828281518110612667576126676138f2565b602002602001015160000151838381518110612685576126856138f2565b602002602001015160200151611896565b806126a08161391e565b915050612649565b6126b061281f565b6001600160a01b0381166127155760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c7565b61271e81612dcb565b50565b602083015151835160009190825b8281101561281457612742600283613a5d565b61ffff166000036127a3578587602001518281518110612764576127646138f2565b6020026020010151604051602001612786929190918252602082015260400190565b6040516020818303038152906040528051906020012095506127f5565b866020015181815181106127b9576127b96138f2565b6020026020010151866040516020016127dc929190918252602082015260400190565b6040516020818303038152906040528051906020012095505b612800600283613a7e565b91508061280c8161391e565b91505061272f565b505050911492915050565b6000546001600160a01b03163314610f325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c7565b6001600160a01b038116600090815260026020908152604080832054600a54600b54600c90945291909320549091906128bd906128b6908461394a565b8490612d1e565b6001600160a01b0385166000908152600d6020526040812080549091906128e5908490613937565b90915550506001600160a01b0384166000908152600c60209081526040808320859055600e90915290205461291e906128b6908361394a565b6001600160a01b0385166000908152600f602052604081208054909190612946908490613937565b90915550506001600160a01b038085166000908152600e602090815260408083208590558051639845755960e01b8152905192937f000000000000000000000000000000000000000000000000000000000000000016926398457559926004808401939192918290030181865afa1580156129c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e9919061395d565b60405163bf928f8b60e01b81526001600160a01b0387811660048301529192509082169063bf928f8b90602401600060405180830381600087803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b505050505050505050565b6000612a5b3384612e1b565b90506000612a71836001600160401b03166125d5565b90506000612a7f84426139a9565b3360009081526003602052604090208054919250906001600160401b03831690829086908110612ab157612ab16138f2565b60009182526020909120600160029092020101546001600160401b031610612aeb5760405162461bcd60e51b81526004016108c7906139d0565b6000818581548110612aff57612aff6138f2565b90600052602060002090600202016000015490506000612b6a838781548110612b2a57612b2a6138f2565b906000526020600020906002020160010160089054906101000a90046001600160801b03166001600160801b0316848881548110610ce657610ce66138f2565b83549091508390612b7d9060019061394a565b81548110612b8d57612b8d6138f2565b9060005260206000209060020201838781548110612bad57612bad6138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b039091161790558254839080612c4157612c41613993565b600082815260208120600260001990930192830201818155600101559055612c6b33838688612f26565b6000612c80836001600160801b038816612d1e565b90508181600854612c919190613937565b612c9b919061394a565b600855336000908152600260205260409020548290612cbb908390613937565b612cc5919061394a565b33600081815260026020526040908190209290925590517fe2d155d9d74decc198a9a9b4f5bddb24ee0842ee745c9ce57e3573b971e50d9d90612d0b9086815260200190565b60405180910390a2505050505050505050565b6000612d2c6012600a613b83565b612d368385613b8f565b612d409190613ba6565b9392505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610c269085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261304c565b600081612dc16012600a613b83565b612d369085613b8f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216600090815260036020526040812054815b81811015612eb8576001600160a01b038516600090815260036020526040902080546001600160401b038616919083908110612e7457612e746138f2565b6000918252602090912060029091020160010154600160c01b90046001600160401b031603612ea6579150610d649050565b80612eb08161391e565b915050612e36565b5060405162461bcd60e51b81526020600482015260126024820152711b1bd8dac8191bd95cdb89dd08195e1a5cdd60721b60448201526064016108c7565b6040516001600160a01b038316602482015260448101829052610f1090849063a9059cbb60e01b90606401612d7b565b6006546001600160a01b038516600090815260036020908152604080832081516080810183528881526001600160401b038881168286019081526001600160801b03808a1695840195865297821660608401818152855460018181018855968a529790982093516002909702909301958655519483018054945196518216600160c01b026001600160c01b0397909816600160401b026001600160c01b031990951695909116949094179290921793909316939093179055612fe99082906139a9565b6006805467ffffffffffffffff19166001600160401b03929092169190911790555050505050565b600061301f6012600a613b83565b6130298385613bba565b612d409190613be5565b6000816130426012600a613b83565b6130299085613bba565b60006130a1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131219092919063ffffffff16565b90508051600014806130c25750808060200190518101906130c29190613bff565b610f105760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016108c7565b60606131308484600085613138565b949350505050565b6060824710156131995760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016108c7565b600080866001600160a01b031685876040516131b59190613c40565b60006040518083038185875af1925050503d80600081146131f2576040519150601f19603f3d011682016040523d82523d6000602084013e6131f7565b606091505b509150915061320887838387613213565b979650505050505050565b6060831561328257825160000361327b576001600160a01b0385163b61327b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108c7565b5081613130565b61313083838151156132975781518083602001fd5b8060405162461bcd60e51b81526004016108c79190613c5c565b508054600082556002029060005260206000209081019061271e91905b808211156132e857600080825560018201556002016132ce565b5090565b6001600160a01b038116811461271e57600080fd5b60006020828403121561331357600080fd5b8135612d40816132ec565b602080825282518282018190526000919060409081850190868401855b8281101561338a57815180518552868101516001600160401b0390811688870152868201516001600160801b03168787015260609182015116908501526080909301929085019060010161333b565b5091979650505050505050565b600080604083850312156133aa57600080fd5b8235915060208301356001600160401b038111156133c757600080fd5b8301604081860312156133d957600080fd5b809150509250929050565b60008083601f8401126133f657600080fd5b5081356001600160401b0381111561340d57600080fd5b6020830191508360208260051b850101111561342857600080fd5b9250929050565b80356001600160401b038116811461344657600080fd5b919050565b60008060006040848603121561346057600080fd5b83356001600160401b0381111561347657600080fd5b613482868287016133e4565b909450925061349590506020850161342f565b90509250925092565b600080604083850312156134b157600080fd5b823591506134c16020840161342f565b90509250929050565b600080604083850312156134dd57600080fd5b50508035926020909101359150565b801515811461271e57600080fd5b60008060006060848603121561350f57600080fd5b8335925061351f6020850161342f565b9150604084013561352f816134ec565b809150509250925092565b6000806040838503121561354d57600080fd5b6135568361342f565b91506134c16020840161342f565b60008060006040848603121561357957600080fd5b8335613584816132ec565b925060208401356001600160401b0381111561359f57600080fd5b6135ab868287016133e4565b9497909650939450505050565b6000602082840312156135ca57600080fd5b612d408261342f565b600080604083850312156135e657600080fd5b8235613556816132ec565b6000806000806080858703121561360757600080fd5b843593506136176020860161342f565b92506040850135613627816134ec565b91506060850135613637816132ec565b939692955090935050565b6000806040838503121561365557600080fd5b8235613660816132ec565b946020939093013593505050565b60006020828403121561368057600080fd5b81356001600160801b0381168114612d4057600080fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156136cf576136cf613697565b60405290565b604051601f8201601f191681016001600160401b03811182821017156136fd576136fd613697565b604052919050565b60006001600160401b0382111561371e5761371e613697565b5060051b60200190565b6000602080838503121561373b57600080fd5b82356001600160401b0381111561375157600080fd5b8301601f8101851361376257600080fd5b803561377561377082613705565b6136d5565b81815260069190911b8201830190838101908783111561379457600080fd5b928401925b8284101561320857604084890312156137b25760008081fd5b6137ba6136ad565b84356137c5816132ec565b81526137d285870161342f565b8187015282526040939093019290840190613799565b6000604082360312156137fa57600080fd5b6138026136ad565b823561ffff8116811461381457600080fd5b81526020838101356001600160401b0381111561383057600080fd5b840136601f82011261384157600080fd5b803561384f61377082613705565b81815260059190911b8201830190838101903683111561386e57600080fd5b928401925b8284101561388c57833582529284019290840190613873565b938501939093525091949350505050565b60208082526010908201526f1b1bd8dad95c881cdd5cdc195b99195960821b604082015260600190565b6020808252601190820152701b1bd8dac81d1a5b59481a5b9d985b1a59607a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161393057613930613908565b5060010190565b80820180821115610d6457610d64613908565b81810381811115610d6457610d64613908565b60006020828403121561396f57600080fd5b8151612d40816132ec565b60006020828403121561398c57600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fd5b6001600160401b038181168382160190808211156139c9576139c9613908565b5092915050565b6020808252601e908201527f63616e6e6f74206d6f76652074686520756e6c6f636b2074696d652075700000604082015260600190565b6001600160801b038181168382160190808211156139c9576139c9613908565b6001600160801b038281168282160390808211156139c9576139c9613908565b634e487b7160e01b600052601260045260246000fd5b600061ffff80841680613a7257613a72613a47565b92169190910692915050565b600061ffff80841680613a9357613a93613a47565b92169190910492915050565b600181815b80851115613ada578160001904821115613ac057613ac0613908565b80851615613acd57918102915b93841c9390800290613aa4565b509250929050565b600082613af157506001610d64565b81613afe57506000610d64565b8160018114613b145760028114613b1e57613b3a565b6001915050610d64565b60ff841115613b2f57613b2f613908565b50506001821b610d64565b5060208310610133831016604e8410600b8410161715613b5d575081810a610d64565b613b678383613a9f565b8060001904821115613b7b57613b7b613908565b029392505050565b6000612d408383613ae2565b8082028115828204841417610d6457610d64613908565b600082613bb557613bb5613a47565b500490565b6001600160801b03818116838216028082169190828114613bdd57613bdd613908565b505092915050565b60006001600160801b0380841680613a9357613a93613a47565b600060208284031215613c1157600080fd5b8151612d40816134ec565b60005b83811015613c37578181015183820152602001613c1f565b50506000910152565b60008251613c52818460208701613c1c565b9190910192915050565b6020815260008251806020840152613c7b816040850160208701613c1c565b601f01601f1916919091016040019291505056fea2646970667358221220110a4a0bdcb2a334a38a1327bc995e846ea2733286b8c500341b4b85048b6e7164736f6c634300081100330000000000000000000000002790ec478f150a98f5d96755601a26403df57eae0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc000000000000000000000000b27dc5f8286f063f11491c8f349053cb37718bea000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd520000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2bdb5e1bfbc1c8e7f169a5d5ca031d8a814267b7fe0af8f3eca2dc0a8a942719c5
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c8063715018a611610182578063a6aed923116100e9578063ddecf662116100a2578063edaf69bd1161007c578063edaf69bd14610763578063f2fde38b14610776578063f77c479114610789578063f816144e146107b057600080fd5b8063ddecf662146106db578063dfb142ae14610725578063ea312d761461073857600080fd5b8063a6aed92314610685578063bb3cac5414610698578063bf4b3e65146106ab578063bf86d690146106b3578063c5890d2d146106c0578063d294f093146106d357600080fd5b80638da5cb5b1161013b5780638da5cb5b146105f4578063923c1d611461060557806393ed9d011461062c578063984acb491461063f5780639ae697bf146106525780639be65a601461067257600080fd5b8063715018a61461055757806378f89c201461055f5780637907706f146105725780637bf500c8146105855780637e0b2492146105a5578063806019c1146105cd57600080fd5b806346e919d0116102265780635f07112f116101df5780635f07112f1461049b57806361d027b3146104ae578063631516c2146104ed578063645d28a8146104f65780636a4874a11461051d57806370a082311461054457600080fd5b806346e919d0146104305780634f348758146104435780635219c5121461045657806356891412146104695780635cad88eb146104725780635ee26ad01461047b57600080fd5b80631c91607f116102785780631c91607f1461038757806326a4c842146103a757806328a81039146103ba5780632a324607146103e35780632eb4a7ab146103f65780633efa99791461041d57600080fd5b80630259ef58146102c05780630499abd4146102e95780630b70608f1461031757806310b9e5831461032c57806311e1dc1e146103345780631b93f66d14610354575b600080fd5b6102d36102ce366004613301565b6107b9565b6040516102e0919061331e565b60405180910390f35b6103096102f7366004613301565b600c6020526000908152604090205481565b6040519081526020016102e0565b61032a610325366004613397565b61086c565b005b61032a610ad5565b610309610342366004613301565b600e6020526000908152604090205481565b610377610362366004613301565b60056020526000908152604090205460ff1681565b60405190151581526020016102e0565b610309610395366004613301565b600f6020526000908152604090205481565b61032a6103b536600461344b565b610b68565b6103096103c8366004613301565b6001600160a01b031660009081526002602052604090205490565b6103096103f1366004613301565b610c2c565b6103097fdb5e1bfbc1c8e7f169a5d5ca031d8a814267b7fe0af8f3eca2dc0a8a942719c581565b61032a61042b36600461349e565b610d26565b61030961043e366004613301565b610d36565b61032a6104513660046134ca565b610d6a565b610309610464366004613301565b610e5b565b61030960075481565b610309600a5481565b610309610489366004613301565b60026020526000908152604090205481565b61032a6104a93660046134fa565b610f04565b6104d57f000000000000000000000000b27dc5f8286f063f11491c8f349053cb37718bea81565b6040516001600160a01b0390911681526020016102e0565b61030960085481565b6104d57f0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc81565b6104d57f000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd5281565b610309610552366004613301565b610f15565b61032a610f20565b61030961056d366004613301565b610f34565b61032a61058036600461353a565b611036565b610309610593366004613301565b600d6020526000908152604090205481565b6105b86105b3366004613301565b6110b1565b604080519283526020830191909152016102e0565b6103097f00000000000000000000000000000000000000000000000000000000669f916781565b6000546001600160a01b03166104d5565b6104d57f0000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b61030961063a366004613564565b61116b565b61032a61064d3660046135b8565b61148a565b610309610660366004613301565b60016020526000908152604090205481565b61032a610680366004613301565b6116c7565b61032a6106933660046135d3565b611896565b6103096106a6366004613301565b611c4a565b610309611c94565b6009546103779060ff1681565b61032a6106ce3660046135f1565b611ca4565b6105b861214b565b6106ee6106e9366004613642565b61223a565b604080519485526001600160401b0393841660208601526001600160801b03909216918401919091521660608201526080016102e0565b610309610733366004613301565b61229a565b61074b61074636600461366e565b6125d5565b6040516001600160801b0390911681526020016102e0565b61032a610771366004613728565b612646565b61032a610784366004613301565b6126a8565b6104d57f0000000000000000000000002790ec478f150a98f5d96755601a26403df57eae81565b610309600b5481565b6001600160a01b0381166000908152600360209081526040808320805482518185028101850190935280835260609492939192909184015b828210156108615760008481526020908190206040805160808101825260028602909201805483526001908101546001600160401b03808216858701526001600160801b03600160401b83041693850193909352600160c01b9004909116606083015290835290920191016107f1565b505050509050919050565b7f00000000000000000000000000000000000000000000000000000000669f916742106108d05760405162461bcd60e51b815260206004820152600d60248201526c185a5c991c9bdc08195b991959609a1b60448201526064015b60405180910390fd5b3360009081526005602052604090205460ff16156109225760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b60448201526064016108c7565b670de0b6b3a764000082101561097a5760405162461bcd60e51b815260206004820152601860248201527f616d6f756e742063616e6e6f742062652062656c6f772031000000000000000060448201526064016108c7565b6730927f74c9de00008211156109d25760405162461bcd60e51b815260206004820181905260248201527f616d6f756e742065786365656473206d61782061697264726f7020626f6f737460448201526064016108c7565b6040516bffffffffffffffffffffffff193360601b16602082015260348101839052600090605401604051602081830303815290604052805190602001209050610a48817fdb5e1bfbc1c8e7f169a5d5ca031d8a814267b7fe0af8f3eca2dc0a8a942719c584610a41906137e8565b9190612721565b610a845760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b60448201526064016108c7565b3360008181526004602052604090819020859055517ffb7c165a21b698d172209fd3fbb4a907042c12438cd506666064cd98e0a142aa90610ac89086815260200190565b60405180910390a2505050565b610add61281f565b60095460ff1615610b305760405162461bcd60e51b815260206004820152601860248201527f6c6f636b657220616c72656164792073757370656e646564000000000000000060448201526064016108c7565b6009805460ff191660011790556040517f4426aa1fb73e391071491fcfe21a88b5c38a0a0333a1f6e77161470439704cf890600090a1565b60095460ff1615610b8b5760405162461bcd60e51b81526004016108c79061389d565b6001600160401b038116629e340011801590610bb4575063013c68006001600160401b03821611155b610bd05760405162461bcd60e51b81526004016108c7906138c7565b610bd933612879565b60005b82811015610c2657610c14848483818110610bf957610bf96138f2565b9050602002016020810190610c0e91906135b8565b83612a4f565b80610c1e8161391e565b915050610bdc565b50505050565b6001600160a01b03811660009081526003602052604081208054829190825b81811015610d1c57426001600160801b0316838281548110610c6f57610c6f6138f2565b60009182526020909120600160029092020101546001600160401b031611610d0a57610cfd838281548110610ca657610ca66138f2565b906000526020600020906002020160010160089054906101000a90046001600160801b03166001600160801b0316848381548110610ce657610ce66138f2565b600091825260209091206002909102015490612d1e565b610d079085613937565b93505b80610d148161391e565b915050610c4b565b5091949350505050565b610d3282826000610f04565b5050565b6000610d4182610c2c565b6001600160a01b038316600090815260026020526040902054610d64919061394a565b92915050565b610d9f6001600160a01b037f000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd5216333085612d47565b610dd46001600160a01b037f0000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2b16333084612d47565b600854610de2908390612db2565b600a6000828254610df39190613937565b9091555050600854610e06908290612db2565b600b6000828254610e179190613937565b9091555050604080518381526020810183905233917f213e72af0d3613bd643cff3059f872c1015e6541624e37872bf95eefbaf220a8910160405180910390a25050565b6001600160a01b03811660009081526003602052604081208054829190825b81811015610d1c57426001600160801b0316838281548110610e9e57610e9e6138f2565b60009182526020909120600160029092020101546001600160401b031611610ef257828181548110610ed257610ed26138f2565b90600052602060002090600202016000015484610eef9190613937565b93505b80610efc8161391e565b915050610e7a565b610f1083838333611ca4565b505050565b6000610d6482610f34565b610f2861281f565b610f326000612dcb565b565b6000610d647f0000000000000000000000002790ec478f150a98f5d96755601a26403df57eae6001600160a01b03166348439e7e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbb919061395d565b60405163067ba3d960e41b81526001600160a01b03858116600483015291909116906367ba3d9090602401602060405180830381865afa158015611003573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611027919061397a565b61103084610d36565b90612d1e565b60095460ff16156110595760405162461bcd60e51b81526004016108c79061389d565b6001600160401b038116629e340011801590611082575063013c68006001600160401b03821611155b61109e5760405162461bcd60e51b81526004016108c7906138c7565b6110a733612879565b610d328282612a4f565b6001600160a01b038116600090815260026020908152604080832054600c909252822054600a548392916110f0916110e9919061394a565b8290612d1e565b6001600160a01b0385166000908152600d60205260409020546111139190613937565b6001600160a01b0385166000908152600e6020526040902054600b54919450611140916110e9919061394a565b6001600160a01b0385166000908152600f60205260409020546111639190613937565b915050915091565b600061117633612879565b3360009081526003602052604081208190815b8581101561139c5760006111c3338989858181106111a9576111a96138f2565b90506020020160208101906111be91906135b8565b612e1b565b60095490915060ff16806112055750428382815481106111e5576111e56138f2565b60009182526020909120600160029092020101546001600160401b031611155b6112445760405162461bcd60e51b815260206004820152601060248201526f1b1bd8dac81b9bdd08195e1c1a5c995960821b60448201526064016108c7565b828181548110611256576112566138f2565b906000526020600020906002020160000154856112739190613937565b945061128a838281548110610ca657610ca66138f2565b6112949085613937565b835490945083906112a79060019061394a565b815481106112b7576112b76138f2565b90600052602060002090600202018382815481106112d7576112d76138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b03909116179055825483908061136b5761136b613993565b60008281526020812060026000199093019283020181815560010155905550806113948161391e565b915050611189565b5082600760008282546113af919061394a565b9250508190555081600860008282546113c8919061394a565b909155505033600090815260016020526040812080548592906113ec90849061394a565b9091555050336000908152600260205260408120805484929061141090849061394a565b9091555061144a90506001600160a01b037f0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc168885612ef6565b60405183815233907fb291e2a2847a5ad6d47409943306c6d6e8c63a9855b849701b868191e94789709060200160405180910390a2509095945050505050565b60095460ff16156114ad5760405162461bcd60e51b81526004016108c79061389d565b6001600160401b038116629e3400118015906114d6575063013c68006001600160401b03821611155b6114f25760405162461bcd60e51b81526004016108c7906138c7565b6114fb33612879565b600061150f826001600160401b03166125d5565b9050600061151d83426139a9565b336000908152600360205260408120549192505b818110156115b25733600090815260036020526040902080546001600160401b038516919083908110611566576115666138f2565b60009182526020909120600160029092020101546001600160401b0316106115a05760405162461bcd60e51b81526004016108c7906139d0565b806115aa8161391e565b915050611531565b503360009081526003602052604081206115cb916132b1565b3360009081526002602052604081205460088054919290916115ee90849061394a565b9091555050336000818152600260209081526040808320839055600190915290205461161c91908486612f26565b3360009081526001602052604081205461163f906001600160801b038616612d1e565b905080600860008282546116539190613937565b90915550503360009081526002602052604081208054839290611677908490613937565b9091555050336000818152600160209081526040918290205491519182527fe2d155d9d74decc198a9a9b4f5bddb24ee0842ee745c9ce57e3573b971e50d9d910160405180910390a25050505050565b7f0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc6001600160a01b0316816001600160a01b03161415801561173b57507f000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd526001600160a01b0316816001600160a01b031614155b801561177957507f0000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b0316816001600160a01b031614155b6117bd5760405162461bcd60e51b815260206004820152601560248201527431b0b73737ba103bb4ba34323930bb903a37b5b2b760591b60448201526064016108c7565b6040516370a0823160e01b8152306004820152819061185e907f000000000000000000000000b27dc5f8286f063f11491c8f349053cb37718bea906001600160a01b038416906370a0823190602401602060405180830381865afa158015611829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184d919061397a565b6001600160a01b0384169190612ef6565b6040516001600160a01b038316907f17a79be10b6da9324a110f0ea6d3043db38f1eee6e2ee1dbfa7272338e39da4590600090a25050565b60006118a28383612e1b565b6001600160a01b03841660009081526003602052604090208054919250906001600160801b034216906224ea00908390859081106118e2576118e26138f2565b600091825260209091206001600290920201015461190991906001600160401b0316613a07565b6001600160801b031611156119585760405162461bcd60e51b815260206004820152601560248201527463616e6e6f74206b69636b2074686973206c6f636b60581b60448201526064016108c7565b61196184612879565b6000818381548110611975576119756138f2565b9060005260206000209060020201600001549050806007600082825461199b919061394a565b925050819055506119e28284815481106119b7576119b76138f2565b60009182526020909120600290910201600101548290600160401b90046001600160801b0316612d1e565b600860008282546119f3919061394a565b90915550506001600160a01b03851660009081526001602052604081208054839290611a2090849061394a565b92505081905550611a3c8284815481106119b7576119b76138f2565b6001600160a01b03861660009081526002602052604081208054909190611a6490849061394a565b9091555060009050611a7e8267016345785d8a0000612d1e565b9050683635c9adc5dea00000811115611a9d5750683635c9adc5dea000005b611adc86611aab838561394a565b6001600160a01b037f0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc169190612ef6565b611b106001600160a01b037f0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc163383612ef6565b60405182815233906001600160a01b038816907f9716d4c8630c7c1a47a462f169d1764a38687f7532baf2bd74a791afc20030e69060200160405180910390a382548390611b609060019061394a565b81548110611b7057611b706138f2565b9060005260206000209060020201838581548110611b9057611b906138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b039091161790558254839080611c2457611c24613993565b600082815260208120600260001990930192830201818155600101559055505050505050565b6001600160a01b0381166000908152600460205260408120548103611c785750670de0b6b3a7640000919050565b506001600160a01b031660009081526004602052604090205490565b6000611c9f3361229a565b905090565b60095460ff1615611cc75760405162461bcd60e51b81526004016108c79061389d565b678ac7230489e80000841015611d125760405162461bcd60e51b815260206004820152601060248201526f185b5bdd5b9d081d1bdbc81cdb585b1b60821b60448201526064016108c7565b6001600160401b038316629e340011801590611d3b575063013c68006001600160401b03841611155b611d575760405162461bcd60e51b81526004016108c7906138c7565b811580611d6c5750336001600160a01b038216145b611daf5760405162461bcd60e51b81526020600482015260146024820152733932b637b1b59037b7363c903337b91039b2b63360611b60448201526064016108c7565b6001600160a01b038116600090815260036020526040902054600a11611e085760405162461bcd60e51b815260206004820152600e60248201526d746f6f206d616e79206c6f636b7360901b60448201526064016108c7565b611e1181612879565b611e466001600160a01b037f0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc16333087612d47565b6000611e5a846001600160401b03166125d5565b90506000611e6733611c4a565b9050670de0b6b3a7640000811115611eb957336000908152600560205260409020805460ff19166001179055611ea66001600160801b03831682613011565b3360009081526004602052604081205591505b6000611ec586426139a9565b905060008515612040576001600160a01b038516600090815260036020526040812054905b81811015611f74576001600160a01b038716600090815260036020526040902080546001600160401b038616919083908110611f2857611f286138f2565b60009182526020909120600160029092020101546001600160401b031610611f625760405162461bcd60e51b81526004016108c7906139d0565b80611f6c8161391e565b915050611eea565b506001600160a01b0386166000908152600360205260408120611f96916132b1565b6001600160a01b0386166000908152600260205260408120546008805491929091611fc290849061394a565b90915550506001600160a01b03861660009081526002602090815260408083208390556001909152902054612005908790611ffe908c90613937565b8588612f26565b6001600160a01b038616600090815260016020526040902054612038906001600160801b03871690611030908c90613937565b915050612062565b61204c85898487612f26565b61205f886001600160801b038616612d1e565b90505b87600760008282546120749190613937565b92505081905550806008600082825461208d9190613937565b90915550506001600160a01b038516600090815260016020526040812080548a92906120ba908490613937565b90915550506001600160a01b038516600090815260026020526040812080548392906120e7908490613937565b9091555050604080518981526001600160401b03841660208201528715158183015290516001600160a01b038716917fca8d506eda84f8ed07c2908ae102299d34888ef5e19b97f56e4d6fcd1104c31e919081900360600190a25050505050505050565b60008061215733612879565b5050336000818152600d6020908152604080832054600f9092529091205490916121ac907f000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd526001600160a01b03169084612ef6565b6121e06001600160a01b037f0000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2b163383612ef6565b336000818152600d60209081526040808320839055600f82528083209290925581518581529081018490527f1ac537f0ad67b64ac68a04587ff3a4cb6977de22eb2c37ee560897a92c6d07c7910160405180910390a29091565b6003602052816000526040600020818154811061225657600080fd5b6000918252602090912060029091020180546001909101549092506001600160401b0380821692506001600160801b03600160401b83041691600160c01b90041684565b60006001600160a01b0382166122e85760405162461bcd60e51b815260206004820152601360248201527234b73b30b634b2103232b9ba34b730ba34b7b760691b60448201526064016108c7565b6122f133612879565b33600090815260036020526040812080548291905b80156124e95761231760018261394a565b60095490915060ff1680612359575042828281548110612339576123396138f2565b60009182526020909120600160029092020101546001600160401b031611155b156124e457818181548110612370576123706138f2565b9060005260206000209060020201600001548461238d9190613937565b93506123e48282815481106123a4576123a46138f2565b906000526020600020906002020160010160089054906101000a90046001600160801b03166001600160801b0316838381548110610ce657610ce66138f2565b6123ee9084613937565b825490935082906124019060019061394a565b81548110612411576124116138f2565b9060005260206000209060020201828281548110612431576124316138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b0390911617905581548290806124c5576124c5613993565b6000828152602081206002600019909301928302018181556001015590555b612306565b83600760008282546124fb919061394a565b925050819055508260086000828254612514919061394a565b9091555050336000908152600160205260408120805486929061253890849061394a565b9091555050336000908152600260205260408120805485929061255c90849061394a565b9091555061259690506001600160a01b037f0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc168786612ef6565b60405184815233907fb291e2a2847a5ad6d47409943306c6d6e8c63a9855b849701b868191e94789709060200160405180910390a25091949350505050565b6000670de0b6b3a764000061263c6126136125f7629e340063013c6800613a27565b612604629e340087613a27565b6001600160801b031690613033565b61262d670de0b6b3a76400006714d1120d7b160000613a27565b6001600160801b031690613011565b610d649190613a07565b60005b8151811015610d3257612696828281518110612667576126676138f2565b602002602001015160000151838381518110612685576126856138f2565b602002602001015160200151611896565b806126a08161391e565b915050612649565b6126b061281f565b6001600160a01b0381166127155760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c7565b61271e81612dcb565b50565b602083015151835160009190825b8281101561281457612742600283613a5d565b61ffff166000036127a3578587602001518281518110612764576127646138f2565b6020026020010151604051602001612786929190918252602082015260400190565b6040516020818303038152906040528051906020012095506127f5565b866020015181815181106127b9576127b96138f2565b6020026020010151866040516020016127dc929190918252602082015260400190565b6040516020818303038152906040528051906020012095505b612800600283613a7e565b91508061280c8161391e565b91505061272f565b505050911492915050565b6000546001600160a01b03163314610f325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c7565b6001600160a01b038116600090815260026020908152604080832054600a54600b54600c90945291909320549091906128bd906128b6908461394a565b8490612d1e565b6001600160a01b0385166000908152600d6020526040812080549091906128e5908490613937565b90915550506001600160a01b0384166000908152600c60209081526040808320859055600e90915290205461291e906128b6908361394a565b6001600160a01b0385166000908152600f602052604081208054909190612946908490613937565b90915550506001600160a01b038085166000908152600e602090815260408083208590558051639845755960e01b8152905192937f0000000000000000000000002790ec478f150a98f5d96755601a26403df57eae16926398457559926004808401939192918290030181865afa1580156129c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e9919061395d565b60405163bf928f8b60e01b81526001600160a01b0387811660048301529192509082169063bf928f8b90602401600060405180830381600087803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b505050505050505050565b6000612a5b3384612e1b565b90506000612a71836001600160401b03166125d5565b90506000612a7f84426139a9565b3360009081526003602052604090208054919250906001600160401b03831690829086908110612ab157612ab16138f2565b60009182526020909120600160029092020101546001600160401b031610612aeb5760405162461bcd60e51b81526004016108c7906139d0565b6000818581548110612aff57612aff6138f2565b90600052602060002090600202016000015490506000612b6a838781548110612b2a57612b2a6138f2565b906000526020600020906002020160010160089054906101000a90046001600160801b03166001600160801b0316848881548110610ce657610ce66138f2565b83549091508390612b7d9060019061394a565b81548110612b8d57612b8d6138f2565b9060005260206000209060020201838781548110612bad57612bad6138f2565b6000918252602090912082546002909202019081556001918201805492909101805467ffffffffffffffff1981166001600160401b03948516908117835583546001600160801b03600160401b9182900416026001600160c01b031990921617178082559154600160c01b908190049093169092026001600160c01b039091161790558254839080612c4157612c41613993565b600082815260208120600260001990930192830201818155600101559055612c6b33838688612f26565b6000612c80836001600160801b038816612d1e565b90508181600854612c919190613937565b612c9b919061394a565b600855336000908152600260205260409020548290612cbb908390613937565b612cc5919061394a565b33600081815260026020526040908190209290925590517fe2d155d9d74decc198a9a9b4f5bddb24ee0842ee745c9ce57e3573b971e50d9d90612d0b9086815260200190565b60405180910390a2505050505050505050565b6000612d2c6012600a613b83565b612d368385613b8f565b612d409190613ba6565b9392505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610c269085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261304c565b600081612dc16012600a613b83565b612d369085613b8f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216600090815260036020526040812054815b81811015612eb8576001600160a01b038516600090815260036020526040902080546001600160401b038616919083908110612e7457612e746138f2565b6000918252602090912060029091020160010154600160c01b90046001600160401b031603612ea6579150610d649050565b80612eb08161391e565b915050612e36565b5060405162461bcd60e51b81526020600482015260126024820152711b1bd8dac8191bd95cdb89dd08195e1a5cdd60721b60448201526064016108c7565b6040516001600160a01b038316602482015260448101829052610f1090849063a9059cbb60e01b90606401612d7b565b6006546001600160a01b038516600090815260036020908152604080832081516080810183528881526001600160401b038881168286019081526001600160801b03808a1695840195865297821660608401818152855460018181018855968a529790982093516002909702909301958655519483018054945196518216600160c01b026001600160c01b0397909816600160401b026001600160c01b031990951695909116949094179290921793909316939093179055612fe99082906139a9565b6006805467ffffffffffffffff19166001600160401b03929092169190911790555050505050565b600061301f6012600a613b83565b6130298385613bba565b612d409190613be5565b6000816130426012600a613b83565b6130299085613bba565b60006130a1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131219092919063ffffffff16565b90508051600014806130c25750808060200190518101906130c29190613bff565b610f105760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016108c7565b60606131308484600085613138565b949350505050565b6060824710156131995760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016108c7565b600080866001600160a01b031685876040516131b59190613c40565b60006040518083038185875af1925050503d80600081146131f2576040519150601f19603f3d011682016040523d82523d6000602084013e6131f7565b606091505b509150915061320887838387613213565b979650505050505050565b6060831561328257825160000361327b576001600160a01b0385163b61327b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108c7565b5081613130565b61313083838151156132975781518083602001fd5b8060405162461bcd60e51b81526004016108c79190613c5c565b508054600082556002029060005260206000209081019061271e91905b808211156132e857600080825560018201556002016132ce565b5090565b6001600160a01b038116811461271e57600080fd5b60006020828403121561331357600080fd5b8135612d40816132ec565b602080825282518282018190526000919060409081850190868401855b8281101561338a57815180518552868101516001600160401b0390811688870152868201516001600160801b03168787015260609182015116908501526080909301929085019060010161333b565b5091979650505050505050565b600080604083850312156133aa57600080fd5b8235915060208301356001600160401b038111156133c757600080fd5b8301604081860312156133d957600080fd5b809150509250929050565b60008083601f8401126133f657600080fd5b5081356001600160401b0381111561340d57600080fd5b6020830191508360208260051b850101111561342857600080fd5b9250929050565b80356001600160401b038116811461344657600080fd5b919050565b60008060006040848603121561346057600080fd5b83356001600160401b0381111561347657600080fd5b613482868287016133e4565b909450925061349590506020850161342f565b90509250925092565b600080604083850312156134b157600080fd5b823591506134c16020840161342f565b90509250929050565b600080604083850312156134dd57600080fd5b50508035926020909101359150565b801515811461271e57600080fd5b60008060006060848603121561350f57600080fd5b8335925061351f6020850161342f565b9150604084013561352f816134ec565b809150509250925092565b6000806040838503121561354d57600080fd5b6135568361342f565b91506134c16020840161342f565b60008060006040848603121561357957600080fd5b8335613584816132ec565b925060208401356001600160401b0381111561359f57600080fd5b6135ab868287016133e4565b9497909650939450505050565b6000602082840312156135ca57600080fd5b612d408261342f565b600080604083850312156135e657600080fd5b8235613556816132ec565b6000806000806080858703121561360757600080fd5b843593506136176020860161342f565b92506040850135613627816134ec565b91506060850135613637816132ec565b939692955090935050565b6000806040838503121561365557600080fd5b8235613660816132ec565b946020939093013593505050565b60006020828403121561368057600080fd5b81356001600160801b0381168114612d4057600080fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156136cf576136cf613697565b60405290565b604051601f8201601f191681016001600160401b03811182821017156136fd576136fd613697565b604052919050565b60006001600160401b0382111561371e5761371e613697565b5060051b60200190565b6000602080838503121561373b57600080fd5b82356001600160401b0381111561375157600080fd5b8301601f8101851361376257600080fd5b803561377561377082613705565b6136d5565b81815260069190911b8201830190838101908783111561379457600080fd5b928401925b8284101561320857604084890312156137b25760008081fd5b6137ba6136ad565b84356137c5816132ec565b81526137d285870161342f565b8187015282526040939093019290840190613799565b6000604082360312156137fa57600080fd5b6138026136ad565b823561ffff8116811461381457600080fd5b81526020838101356001600160401b0381111561383057600080fd5b840136601f82011261384157600080fd5b803561384f61377082613705565b81815260059190911b8201830190838101903683111561386e57600080fd5b928401925b8284101561388c57833582529284019290840190613873565b938501939093525091949350505050565b60208082526010908201526f1b1bd8dad95c881cdd5cdc195b99195960821b604082015260600190565b6020808252601190820152701b1bd8dac81d1a5b59481a5b9d985b1a59607a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161393057613930613908565b5060010190565b80820180821115610d6457610d64613908565b81810381811115610d6457610d64613908565b60006020828403121561396f57600080fd5b8151612d40816132ec565b60006020828403121561398c57600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fd5b6001600160401b038181168382160190808211156139c9576139c9613908565b5092915050565b6020808252601e908201527f63616e6e6f74206d6f76652074686520756e6c6f636b2074696d652075700000604082015260600190565b6001600160801b038181168382160190808211156139c9576139c9613908565b6001600160801b038281168282160390808211156139c9576139c9613908565b634e487b7160e01b600052601260045260246000fd5b600061ffff80841680613a7257613a72613a47565b92169190910692915050565b600061ffff80841680613a9357613a93613a47565b92169190910492915050565b600181815b80851115613ada578160001904821115613ac057613ac0613908565b80851615613acd57918102915b93841c9390800290613aa4565b509250929050565b600082613af157506001610d64565b81613afe57506000610d64565b8160018114613b145760028114613b1e57613b3a565b6001915050610d64565b60ff841115613b2f57613b2f613908565b50506001821b610d64565b5060208310610133831016604e8410600b8410161715613b5d575081810a610d64565b613b678383613a9f565b8060001904821115613b7b57613b7b613908565b029392505050565b6000612d408383613ae2565b8082028115828204841417610d6457610d64613908565b600082613bb557613bb5613a47565b500490565b6001600160801b03818116838216028082169190828114613bdd57613bdd613908565b505092915050565b60006001600160801b0380841680613a9357613a93613a47565b600060208284031215613c1157600080fd5b8151612d40816134ec565b60005b83811015613c37578181015183820152602001613c1f565b50506000910152565b60008251613c52818460208701613c1c565b9190910192915050565b6020815260008251806020840152613c7b816040850160208701613c1c565b601f01601f1916919091016040019291505056fea2646970667358221220110a4a0bdcb2a334a38a1327bc995e846ea2733286b8c500341b4b85048b6e7164736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002790ec478f150a98f5d96755601a26403df57eae0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc000000000000000000000000b27dc5f8286f063f11491c8f349053cb37718bea000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd520000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2bdb5e1bfbc1c8e7f169a5d5ca031d8a814267b7fe0af8f3eca2dc0a8a942719c5
-----Decoded View---------------
Arg [0] : _controller (address): 0x2790EC478f150a98F5D96755601a26403DF57EaE
Arg [1] : _cncToken (address): 0x9aE380F0272E2162340a5bB646c354271c0F5cFC
Arg [2] : _treasury (address): 0xB27DC5f8286f063F11491c8f349053cB37718bea
Arg [3] : _crv (address): 0xD533a949740bb3306d119CC777fa900bA034cd52
Arg [4] : _cvx (address): 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B
Arg [5] : _merkleRoot (bytes32): 0xdb5e1bfbc1c8e7f169a5d5ca031d8a814267b7fe0af8f3eca2dc0a8a942719c5
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000002790ec478f150a98f5d96755601a26403df57eae
Arg [1] : 0000000000000000000000009ae380f0272e2162340a5bb646c354271c0f5cfc
Arg [2] : 000000000000000000000000b27dc5f8286f063f11491c8f349053cb37718bea
Arg [3] : 000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52
Arg [4] : 0000000000000000000000004e3fbd56cd56c3e72c1403e103b45db9da5b9d2b
Arg [5] : db5e1bfbc1c8e7f169a5d5ca031d8a814267b7fe0af8f3eca2dc0a8a942719c5
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.247701 | 1,112,615.797 | $275,596.05 |
Loading...
Loading
[ Download: CSV Export ]
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.