Address Contract Verified
Address
0x043e85d562A77b16A375DCC712BcE151839C5941
Balance
0 ETH
Nonce
1
Code Size
3668 bytes
Creator
0x89E89C39...7eb3 at tx 0xb05b3b35...68ec18
Indexed Transactions
0
Contract Bytecode
3668 bytes
0x604060808152600480361015610013575f80fd5b5f3560e01c8063171060ec1461065d5780631752eda81461064257806334025c511461062b57806334b5ec3a146105eb578063481c6a75146105c35780634a3c037a1461059d57806365dded45146105755780636ff1c9bc14610417578063715018a6146103c0578063787a08a61461039a57806379c5b5d01461034d5780638da5cb5b14610326578063923c1d61146102fe5780639a408321146102ce578063b6e6d3fc146102a6578063b78e333b14610266578063c36538841461023e578063d0ebdbe7146101ea578063d7b96d4e146101c25763f2fde38b146100f7575f80fd5b346101be5760203660031901126101be57610110610783565b90610119610dc7565b6001600160a01b0391821692831561016c5750505f54826bffffffffffffffffffffffff60a01b8216175f55167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b5f80fd5b82346101be575f3660031901126101be5760015490516001600160a01b039091168152602090f35b50346101be5760203660031901126101be57356001600160a01b038116908190036101be57610217610dc7565b610222811515610824565b6bffffffffffffffffffffffff60a01b60025416176002555f80f35b82346101be575f3660031901126101be5760035490516001600160a01b039091168152602090f35b346101be5760203660031901126101be5761027f610799565b610287610dc7565b6005805460ff60a81b191691151560a81b60ff60a81b16919091179055005b82346101be575f3660031901126101be5760055490516001600160a01b039091168152602090f35b5090346101be57806003193601126101be576102f76020926102ee6107a8565b90339035610957565b9051908152f35b5090346101be575f3660031901126101be57905490516001600160a01b039091168152602090f35b82346101be575f3660031901126101be575f5490516001600160a01b039091168152602090f35b50346101be5760203660031901126101be57356001600160a01b03818116918290036101be5761037b610dc7565b61038a600554918216156107ea565b6001600160a01b03191617600555005b82346101be575f3660031901126101be5760209060ff60055460a81c1690519015158152f35b346101be575f3660031901126101be576103d8610dc7565b5f80546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b50346101be576020806003193601126101be57610432610783565b61043a610dc7565b83516370a0823160e01b8152308482015282816024816001600160a01b0386165afa90811561056b575f9161053e575b50845163a9059cbb60e01b8482019081523360248301526044808301939093529181525f928392909183906104a0606482610892565b51925af16104ac610918565b8161050e575b50156104ba57005b608492519162461bcd60e51b8352820152602b60248201527f455243323048656c706572733a3a736166655472616e736665723a207472616e60448201526a1cd9995c8819985a5b195960aa1b6064820152fd5b80518015925083908315610526575b5050505f6104b2565b61053693508201810191016108b4565b5f828161051d565b90508281813d8311610564575b6105558183610892565b810103126101be57515f61046a565b503d61054b565b85513d5f823e3d90fd5b5090346101be573660031901126101be5761059b906105926107a8565b90339035610bc5565b005b82346101be575f3660031901126101be5760209060ff60055460a01c1690519015158152f35b82346101be575f3660031901126101be5760025490516001600160a01b039091168152602090f35b346101be5760203660031901126101be57610604610799565b61060c610dc7565b6005805460ff60a01b191691151560a01b60ff60a01b16919091179055005b346101be5761059b61063c366107b7565b91610bc5565b82346101be576020906102f7610657366107b7565b91610957565b50346101be57602090816003193601126101be57610679610783565b92610682610dc7565b6001546001600160a01b039485169492906106a19084168614156107ea565b6106ac851515610824565b82815416825185816044815f63095ea7b360e01b968783528c89840152811960248401525af18015610779579160449187949361075c575b505f868454169660015416968651978895869485528401528160248401525af19081156107535750610725575b600180546001600160a01b03191684179055005b8161074492903d1061074c575b61073c8183610892565b8101906108b4565b505f80610711565b503d610732565b513d5f823e3d90fd5b61077290853d871161074c5761073c8183610892565b505f6106e4565b84513d5f823e3d90fd5b600435906001600160a01b03821682036101be57565b6004359081151582036101be57565b6024359081151582036101be57565b60609060031901126101be57600435906024356001600160a01b03811681036101be579060443580151581036101be5790565b156107f157565b60405162461bcd60e51b815260206004820152600b60248201526a185b1c9958591e481cd95d60aa1b6044820152606490fd5b1561082b57565b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606490fd5b6040810190811067ffffffffffffffff82111761087e57604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761087e57604052565b908160209103126101be575180151581036101be5790565b156108d357565b60405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e20300000006044820152606490fd5b3d15610952573d9067ffffffffffffffff821161087e5760405191610947601f8201601f191660200184610892565b82523d5f602084013e565b606090565b919060ff60055460a81c16610b95576109718315156108cc565b60018060a01b0390600492828454165f6040918251906323b872dd60e01b825233888301523060248301528860448301528160648160209586945af1908115610b8b575f91610b6e575b5015610b36578460015416856002541683518381019163e2ab691d60e01b835260248201528960448201525f60648201526064815260a0810181811067ffffffffffffffff821117610b23578694938b935f809481948a5251925af197610a20610918565b505f95610ae1575b6005548551633807aabd60e01b81526001600160a01b0389169281019283526020830193909352839183918a169082905f9082906040015b03925af1801561077957908291610ab8575b50508251968888521515908701521515908501521515606084015216907fdbe9ff3ca3378cc55a113a58be1ca0d4bc87607d80867790fd17aae33eef707160803392a390565b813d8311610ada575b610acb8183610892565b810103126101be57805f610a72565b503d610ac1565b945081610a60915f808a600254168851828682019163c53b573d60e01b83528c8152610b0c81610862565b51925af1610b18610918565b509691509150610a28565b60418a634e487b7160e01b5f525260245ffd5b8590606492519162461bcd60e51b8352820152601360248201527218dd9e081d1c985b9cd9995c8819985a5b1959606a1b6044820152fd5b610b859150823d841161074c5761073c8183610892565b5f6109bb565b83513d5f823e3d90fd5b60405162461bcd60e51b815260206004820152600860248201526731b7b7b63237bbb760c11b6044820152606490fd5b9190610bd28315156108cc565b60ff60055460a01c16610d8257600354604080516323b872dd60e01b815233600482015261dead6024820152604481018690526001600160a01b03949192602091908290829060649082905f908b165af1908115610779575f91610d65575b5015610d2257815f92610ce8575b6005548451633807aabd60e01b81526001600160a01b038716600482015260248101899052908390829060449082905f908c165af1801561056b57908391610cbf575b5050835196875215159086015215159084015216907f8a203cd0ae8b1c41b7f5ba77f60efe2dbabc71d63b9a1543abb5f834bbed380960603392a3565b813d8311610ce1575b610cd28183610892565b810103126101be57815f610c82565b503d610cc8565b91505f8086600254168551828582019163c53b573d60e01b835260048152610d0f81610862565b51925af1610d1b610918565b5091610c3f565b60649083519062461bcd60e51b82526004820152601760248201527f62656e74435658207472616e73666572206661696c65640000000000000000006044820152fd5b610d7c9150823d841161074c5761073c8183610892565b5f610c31565b60405162461bcd60e51b815260206004820152601860248201527f4d6967726174696f6e20697320696e20636f6f6c646f776e00000000000000006044820152606490fd5b5f546001600160a01b03163303610dda57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fdfea264697066735822122053dc0a11db7ef9f2399b69734981b062af858c9266c31816990f679e617fd23a64736f6c63430008190033
Verified Source Code Full Match
Compiler: v0.8.25+commit.b61c2a91
EVM: cancun
Optimization: Yes (200 runs)
Ownable.sol 83 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/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);
}
}
IERC20Metadata.sol 6 lines
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../token/ERC20/extensions/IERC20Metadata.sol";
IERC20.sol 78 lines
// 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);
}
IERC20Metadata.sol 28 lines
// 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);
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
IUniswapV2Pair.sol 52 lines
pragma solidity >=0.5.0;
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function kLast() external view returns (uint);
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
TCvxOperator.sol 169 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./libraries/ERC20Helpers.sol";
import "./interfaces/ICvxLocker.sol";
import "./interfaces/IManager.sol";
import "./interfaces/ITCvx.sol";
/**
* @title TCvxOperator
* @notice Contract that generates tCVX and locks CVX or migrates bentCVX 1:1
*/
contract TCvxOperator is Ownable {
ICvxLocker public locker;
IManager public manager;
IERC20 public bentCVX;
IERC20 public cvx;
ITCvx public tCvx;
bool public migrationCooldown;
bool public cooldown;
event Migrated(address indexed user, address indexed recipient, uint256 amount, bool relockAttempted, bool relockSuccess);
event Deposited(address indexed user, address indexed recipient, uint256 amount, bool lockSuccess, bool relockAttempted, bool relockSuccess);
constructor(
address _cvx,
address _locker,
address _manager,
address _bentCVX
) {
cvx = IERC20(_cvx);
bentCVX = IERC20(_bentCVX);
manager = IManager(_manager);
locker = ICvxLocker(_locker);
cvx.approve(_locker, type(uint256).max);
}
/**
* @notice Allows the owner to set the tCVX
*/
function setTCvx(ITCvx _tCvx) external onlyOwner {
require(address(tCvx) == address(0), "already set");
tCvx = _tCvx;
}
/**
* @notice Allows the owner to update the cvx locker address.
* @param _locker Address of the locker
*/
function setLocker(address _locker) external onlyOwner {
require(_locker != address(locker), "already set");
require(_locker != address(0), "Invalid address");
cvx.approve(_locker, type(uint256).max);
cvx.approve(address(locker), 0);
locker = ICvxLocker(_locker);
}
/**
* @notice Allows the owner to update the manager address.
* @param _manager Address of the manager
*/
function setManager(IManager _manager) external onlyOwner {
require(address(_manager) != address(0), "Invalid address");
manager = _manager;
}
/**
@notice withdraws the specified token to the owner in case of emergency
@param _token address The token to withdraw
*/
function emergencyWithdraw(address _token) external onlyOwner {
IERC20 token = IERC20(_token);
uint256 amount = token.balanceOf(address(this));
ERC20Helpers.safeTransfer(_token, msg.sender, amount);
}
/**
* @notice Allows the owner to update the migration cooldown
* @param _cooldown Boolean indicating cooldown
*/
function setMigrationCooldown(bool _cooldown) external onlyOwner {
migrationCooldown = _cooldown;
}
/**
* @notice Allows the owner to update deposits being cooldown or active
* @param _cooldown Boolean indicating cooldown
*/
function setDepositsCooldown(bool _cooldown) external onlyOwner {
cooldown = _cooldown;
}
/**
* @notice Migrate bentCVX tokens and generate tCVX 1:1.
* @param amount The amount of bentCVX to migrate.
* @param processExpiredLocks bool to relock or not
*/
function migrateBentCVX(uint256 amount, bool processExpiredLocks) external {
migrateBentCVXFor(amount, msg.sender, processExpiredLocks);
}
/**
* @notice Migrate bentCVX tokens and generate tCVX 1:1.
* @param amount The amount of bentCVX to migrate.
* @param recipient The user to receive the tCvx
* @param processExpiredLocks bool to relock or not
*/
function migrateBentCVXFor(uint256 amount, address recipient, bool processExpiredLocks) public {
require(amount > 0, "Amount must be greater than 0");
require(!migrationCooldown, "Migration is in cooldown");
require(bentCVX.transferFrom(msg.sender, 0x000000000000000000000000000000000000dEaD, amount), "bentCVX transfer failed");
// Relock any unlocked cvx and don't
// throw exception if it doesn't work
bool relockSuccess;
if (processExpiredLocks)
(relockSuccess,) = address(manager).call(
abi.encodeWithSelector(manager.relock.selector)
);
tCvx.generate(recipient, amount);
emit Migrated(msg.sender, recipient, amount, processExpiredLocks, relockSuccess);
}
/**
* @notice Deposit CVX tokens and generates tCVX 1:1.
* @param amount The amount of CVX to deposit.
* @param processExpiredLocks true if should attempt relock on manager
*/
function deposit(uint256 amount, bool processExpiredLocks) external returns (uint256) {
return depositFor(amount, msg.sender, processExpiredLocks);
}
/**
* @notice Deposit CVX tokens and generates tCVX 1:1 for the recipient
* @param amount amount to deposit
* @param recipient the user to receive the tCVX
* @param processExpiredLocks true if should attempt relock on manager
* @return The amount of tCVX minted to the recipient (equal to `amount`).
*/
function depositFor(uint256 amount, address recipient, bool processExpiredLocks) public returns (uint256) {
require(!cooldown, "cooldown");
require(amount > 0, "Amount must be greater than 0");
require(cvx.transferFrom(msg.sender, address(this), amount), "cvx transfer failed");
// Attempt to lock cvx, if it fails, don't revert
(bool lockSuccess,) = address(locker).call(
abi.encodeWithSelector(locker.lock.selector, address(manager), amount, 0)
);
// Relock any unlocked cvx and don't
// throw exception if it doesn't work
bool relockSuccess;
if (processExpiredLocks)
(relockSuccess,) = address(manager).call(
abi.encodeWithSelector(manager.relock.selector)
);
tCvx.generate(recipient, amount);
emit Deposited(msg.sender, recipient, amount, lockSuccess, processExpiredLocks, relockSuccess);
return amount;
}
}
ICvxLocker.sol 52 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
interface ICvxLocker {
struct LockedBalance {
uint112 amount;
uint112 boosted;
uint32 unlockTime;
}
struct EarnedData {
address token;
uint256 amount;
}
struct Balances {
uint112 locked;
uint112 boosted;
uint32 nextUnlockIndex;
}
function lock(
address _account,
uint256 _amount,
uint256 _spendRatio
) external;
function userLocks(address _user, uint256 index) external view returns (LockedBalance memory);
function balances(address _user) external view returns (Balances memory);
function lockedBalances(address _user)
external
view
returns (
uint256 total,
uint256 unlockable,
uint256 locked,
LockedBalance[] memory lockData
);
function withdrawExpiredLocksTo(address recipient) external;
function processExpiredLocks(bool _relock) external;
function claimableRewards(address _account)
external
view
returns (EarnedData[] memory userRewards);
function getReward(address _account, bool _stake) external;
function lockedBalanceOf(address _user) external view returns (uint256 amount);
function balanceOf(address _user) external view returns (uint256 amount);
}
IManager.sol 6 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
interface IManager {
function relock() external;
}
ITCvx.sol 8 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
interface ITCvx {
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function generate(address receiver, uint256 amount) external returns (uint256);
}
ERC20Helpers.sol 58 lines
// SPDX-License-Identifier: GPL-3.0-or-later
import "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
pragma solidity >=0.6.0;
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library ERC20Helpers {
function safeApprove(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'ERC20Helpers::safeApprove: approve failed'
);
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'ERC20Helpers::safeTransfer: transfer failed'
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'ERC20Helpers::transferFrom: transferFrom failed'
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, 'ERC20Helpers::safeTransferETH: ETH transfer failed');
}
}
Read Contract
bentCVX 0xc3653884 → address
cooldown 0x787a08a6 → bool
cvx 0x923c1d61 → address
locker 0xd7b96d4e → address
manager 0x481c6a75 → address
migrationCooldown 0x4a3c037a → bool
owner 0x8da5cb5b → address
tCvx 0xb6e6d3fc → address
Write Contract 12 functions
These functions modify contract state and require a wallet transaction to execute.
deposit 0x9a408321
uint256 amount
bool processExpiredLocks
returns: uint256
depositFor 0x1752eda8
uint256 amount
address recipient
bool processExpiredLocks
returns: uint256
emergencyWithdraw 0x6ff1c9bc
address _token
migrateBentCVX 0x65dded45
uint256 amount
bool processExpiredLocks
migrateBentCVXFor 0x34025c51
uint256 amount
address recipient
bool processExpiredLocks
renounceOwnership 0x715018a6
No parameters
setDepositsCooldown 0xb78e333b
bool _cooldown
setLocker 0x171060ec
address _locker
setManager 0xd0ebdbe7
address _manager
setMigrationCooldown 0x34b5ec3a
bool _cooldown
setTCvx 0x79c5b5d0
address _tCvx
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address