编译器
0.8.17+commit.8df45f5f
文件 1 的 31:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
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");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
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");
}
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);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
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);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
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);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
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 {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 31:CNCLockerV3.sol
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;
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;
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);
}
function lock(uint256 amount, uint64 lockTime, bool relock_) public override {
lockFor(amount, lockTime, relock_, msg.sender);
}
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_);
}
function executeAvailableUnlocks() external override returns (uint256) {
return executeAvailableUnlocksFor(msg.sender);
}
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;
}
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;
}
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;
}
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);
}
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);
}
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);
}
}
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_;
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;
}
}
文件 3 的 31:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 31:CurvePoolUtils.sol
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);
uint256 internal constant _DEFAULT_IMBALANCE_BUFFER = 30e14;
uint8 internal constant _CURVE_POOL_FEE_DECIMALS = 10;
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) {
toActual = ICurvePoolV2(poolMeta.pool).get_dy(i, j, fromBalance);
} else {
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;
}
}
文件 5 的 31:IBonding.sol
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);
}
文件 6 的 31:IBooster.sol
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);
}
文件 7 的 31:ICNCLockerV3.sol
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;
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);
}
文件 8 的 31:ICNCToken.sol
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);
function addMinter(address newMinter) external;
function renounceMinterRights() external;
function mintInitialDistribution(address distribution) external;
function mintAirdrop(address airdropHandler) external;
function mintAMMRewards(address ammGauge) external;
function mint(address account, uint256 amount) external returns (uint256);
function listMinters() external view returns (address[] memory);
function inflationMintedRatio() external view returns (uint256);
}
文件 9 的 31:ICNCVoteLocker.sol
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);
}
文件 10 的 31:IConicPool.sol
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);
function totalUnderlying() external view returns (uint256);
function getTotalAndPerPoolUnderlying()
external
view
returns (
uint256 totalUnderlying_,
uint256 totalAllocated_,
uint256[] memory perPoolUnderlying_
);
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;
}
文件 11 的 31:IConicPoolWeightManagement.sol
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);
}
文件 12 的 31:IController.sol
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;
function inflationManager() external view returns (IInflationManager);
function setInflationManager(address manager) external;
function curveRegistryCache() external view returns (ICurveRegistryCache);
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;
function switchLpTokenStaker(address _lpTokenStaker) external;
function lpTokenStaker() external view returns (ILpTokenStaker);
function bonding() external view returns (IBonding);
function setBonding(address _bonding) external;
function feeRecipient() external view returns (IFeeRecipient);
function setFeeRecipient(address _feeRecipient) external;
function priceOracle() external view returns (IGenericOracle);
function setPriceOracle(address oracle) external;
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;
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;
function isAllowedMultipleDepositsWithdraws(address poolAddress) external view returns (bool);
function setAllowedMultipleDepositsWithdraws(address account, bool allowed) external;
function getMultipleDepositsWithdrawsWhitelist() external view returns (address[] memory);
function setMinimumTaintedTransferAmount(address token, uint256 amount) external;
function getMinimumTaintedTransferAmount(address token) external view returns (uint256);
function MAX_WEIGHT_UPDATE_MIN_DELAY() external view returns (uint256);
function MIN_WEIGHT_UPDATE_MIN_DELAY() external view returns (uint256);
}
文件 13 的 31:ICurvePoolV1.sol
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);
}
文件 14 的 31:ICurvePoolV2.sol
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);
}
文件 15 的 31:ICurveRegistryCache.sol
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);
function getAllUnderlyingCoins(address pool) external view returns (address[] memory);
}
文件 16 的 31:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 17 的 31:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 18 的 31:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 19 的 31:IFeeRecipient.sol
pragma solidity 0.8.17;
interface IFeeRecipient {
event FeesReceived(address indexed sender, uint256 crvAmount, uint256 cvxAmount);
function receiveFees(uint256 amountCrv, uint256 amountCvx) external;
}
文件 20 的 31:IGenericOracle.sol
pragma solidity 0.8.17;
import "IOracle.sol";
interface IGenericOracle is IOracle {
function getOracle(address token) external view returns (IOracle);
function curveLpToUnderlying(
address curveLpToken,
address underlying,
uint256 curveLpAmount
) external view returns (uint256);
function curveLpToUnderlying(
address curveLpToken,
address underlying,
uint256 curveLpAmount,
uint256 underlyingPrice
) external view returns (uint256);
function underlyingToCurveLp(
address underlying,
address curveLpToken,
uint256 underlyingAmount
) external view returns (uint256);
}
文件 21 的 31:IInflationManager.sol
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;
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);
}
文件 22 的 31:ILpToken.sol
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;
}
文件 23 的 31:ILpTokenStaker.sol
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);
}
文件 24 的 31:IOracle.sol
pragma solidity 0.8.17;
interface IOracle {
event TokenUpdated(address indexed token, address feed, uint256 maxDelay, bool isEthPrice);
function getUSDPrice(address token) external view returns (uint256);
function isTokenSupported(address token) external view returns (bool);
}
文件 25 的 31:IPausable.sol
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;
}
文件 26 的 31:IPoolAdapter.sol
pragma solidity 0.8.17;
interface IPoolAdapter {
enum PriceMode {
Latest,
Cached,
Minimum
}
function deposit(address pool, address underlying, uint256 underlyingAmount) external;
function withdraw(address pool, address underlying, uint256 underlyingAmount) external;
function computePoolValueInUSD(
address conicPool,
address pool
) external view returns (uint256 usdAmount);
function updatePriceCache(address pool) external;
function computePoolValueInUSD(
address conicPool,
address pool,
PriceMode priceMode
) external view returns (uint256 usdAmount);
function computePoolValueInUnderlying(
address conicPool,
address pool,
address underlying,
uint256 underlyingPrice
) external view returns (uint256 underlyingAmount);
function computePoolValueInUnderlying(
address conicPool,
address pool,
address underlying,
uint256 underlyingPrice,
PriceMode priceMode
) external view returns (uint256 underlyingAmount);
function claimEarnings(address conicPool, address pool) external;
function lpToken(address pool) external view returns (address);
function supportsAsset(address pool, address asset) external view returns (bool);
function getCRVEarnedOnConvex(
address account,
address curvePool
) external view returns (uint256);
function executeSanityCheck(address pool) external;
function getAllUnderlyingCoins(address pool) external view returns (address[] memory);
}
文件 27 的 31:IRewardManager.sol
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);
}
文件 28 的 31:MerkleProof.sol
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;
}
}
文件 29 的 31:Ownable.sol
pragma solidity ^0.8.0;
import "Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 30 的 31:SafeERC20.sol
pragma solidity ^0.8.0;
import "IERC20.sol";
import "IERC20Permit.sol";
import "Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
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));
}
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));
}
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));
}
}
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);
}
}
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");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
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");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 31 的 31:ScaledMath.sol
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;
}
}
{
"compilationTarget": {
"CNCLockerV3.sol": "CNCLockerV3"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"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"}]