Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deposit Native | 18470821 | 470 days ago | IN | 0.00001 ETH | 0.00343352 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18470821 | 470 days ago | 0.00001 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
WrappedTokenGateway
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; import {IWrappedToken} from "./interfaces/IWrappedToken.sol"; import {IMaxApyVault} from "./interfaces/IMaxApyVault.sol"; import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol"; /*KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKK0OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO0KKKKKKK KK0dcclllllllllllllllllllllllllllllccccccccccccccccccclx0KKK KOc,dKNWWWWWWWWWWWWWWWWWWWWWWWWWWWWNNNNNNNNNNNNNNNNNXOl';xKK Kd'oWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMX; ,kK Ko'xMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNc .dK Ko'dMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNc .oK Kd'oWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNc .oK KO:,xXWWWWWWWWWWWWWWWWWWWWMMMMMMMMMMMMMMMMMMMMMMMMMMMMNc .oK KKOl,',;;,,,,,,;;,,,,,,,;;cxXMMMMMMMMMMMMMMMMMMMMMMMMMNc .oK KKKKOoc;;;;;;;;;;;;;;;;;;;,.cXMMMMMMMMMMMMMMMMMMMMMMMMNc .oK KKKKKKKKKKKKKKKKKKKK00O00K0:,0MMMMMMMMMMMMMMMMMMMMMMMMNc .oK KKKKKKKKKKKKKKKKKKklcccccld;,0MMMMMMMMMMMMMMMMMMMMMMMMNc .oK KKKKKKKKKKKKKKKKkl;ckXNXOc. '0MMMMMMMMMMMMMMMMMMMMMMMMNc .oK KKKKKKKKKKKKKKkc;l0WMMMMMX; .oKNMMMMMMMMMMMMMMMMMMMMMMNc .oK KKKKKKKKKKKKkc;l0WMMMMMMMWd. .,lddddddxONMMMMMMMMMMMMNc .oK KKKKKKKKKKkc;l0WMMMMMMMMMMWOl::;'. .....:0WMMMMMMMMMMNc .oK KKKKKKK0xc;o0WMMMMMMMMMMMMMMMMMWNk'.;xkko'lNMMMMMMMMMMNc .oK KKKKK0x:;oKWMMMMMMMMMMMMMMMMMMMMMWd..lKKk,lNMMMMMMMMMMNc .oK KKK0x:;oKWMMMMMMMMMMMMMMMMMMMMMMWO, c0Kk,lNMMMMMMMMMMNc .oK KKx:;dKWMMMMMMMMMMMMMMMMMMMMMWN0c. ;kKKk,lNMMMMMMMMMMNc .oK Kx,:KWMMMMMMMMMMMMMMMMMMMMMW0c,. 'oOKKKk,lNMMMMMMMMMMNc .oK Ko'xMMMMMMMMMMMMMMMMMMMMMW0c. 'oOKKKKKk,lNMMMMMMMMMMNc .oK Ko'xMMMMMMMMMMMMMMMMMMMW0c. ':oOKKKKKKKk,lNMMMMMMMMMMNc .oK Ko'xMMMMMMMMMMMMMMMMMW0l. 'oOKKKKKKKKKKk,cNMMMMMMMMMMNc .oK Ko'xMMMMMMMMMMMMMMMW0l. 'oOKKKKKKKKKKKKk,lNMMMMMMMMMMNc .oK Ko'dWMMMMMMMMMMMMW0l. 'oOKKKKKKKKKKKKKKk,cNMMMMMMMMMMX: .oK KO:,xXNWWWWWWWWNOl. 'oOKKKKKKKKKKKKKKKK0c,xNMMMMMMMMNd. .dK KKOl''',,,,,,,,.. 'oOKKKKKKKKKKKKKKKKKKKOl,,ccccccc:' .c0K KKKKOoc:;;;;;;;;:ldOKKKKKKKKKKKKKKKKKKKKKKKkl;'......',cx0KK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK0OOOOOOO0KKK*/ /// @notice Helper contract to interact with a MaxApy Vault utilizing the chain's native token the protocol /// has been deployed to /// @author MaxApy contract WrappedTokenGateway { using SafeTransferLib for address; //////////////////////////////////////////////////////////////// /// CONSTANTS /// //////////////////////////////////////////////////////////////// /// @notice The chain's wrapped native token IWrappedToken public immutable wrappedToken; /// @notice The MaxApy vault linked to this Gateway contract IMaxApyVault public immutable vault; //////////////////////////////////////////////////////////////// /// ERRORS /// //////////////////////////////////////////////////////////////// error InvalidZeroValue(); error FailedNativeTransfer(); error ReceiveNotAllowed(); //////////////////////////////////////////////////////////////// /// EVENTS /// //////////////////////////////////////////////////////////////// /// @notice Emitted on native vault deposits event DepositNative(address indexed recipient, uint256 shares, uint256 amount); /// @notice Emitted on native vault withdrawals event WithdrawNative(address indexed recipient, uint256 shares, uint256 amount); /// @dev `keccak256(bytes("DepositNative(address,uint256,uint256)"))`. uint256 internal constant _DEPOSIT_NATIVE_EVENT_SIGNATURE = 0x6bb902f8baf2580ae3dae24e58f4b874ecca85152076af921bfd172dce1c7e28; /// @dev `keccak256(bytes("WithdrawNative(address,uint256,uint256)"))`. uint256 internal constant _WITHDRAW_NATIVE_EVENT_SIGNATURE = 0x5cb35f4e7dbc40dd34f0d58cec4f5548fc47638cb46d7964e4f07c48e97e4c7d; //////////////////////////////////////////////////////////////// /// CONSTRUCTOR /// //////////////////////////////////////////////////////////////// /// @notice Create the WrappedToken Gateway /// @param _wrappedToken The wrapped token of the chain the contract will be deployed to /// @param _vault The MaxApy vault linked to this Gateway contract constructor(IWrappedToken _wrappedToken, IMaxApyVault _vault) { wrappedToken = _wrappedToken; vault = _vault; address(_wrappedToken).safeApprove(address(_vault), type(uint256).max); } //////////////////////////////////////////////////////////////// /// GATEWAY CORE LOGIC /// //////////////////////////////////////////////////////////////// /// @notice Deposits `msg.value` of `_wrappedToken`, issuing shares to `recipient` /// @param recipient The address to issue the shares from MaxApy's Vault to function depositNative(address recipient) external payable returns (uint256) { // Cache `wrappedToken` and `vault` due to assembly's immutable access restrictions address cachedWrappedToken = address(wrappedToken); address cachedVault = address(vault); assembly ("memory-safe") { // Check if `msg.value` is 0 if iszero(callvalue()) { // Throw the `InvalidZeroValue()` error mstore(0x00, 0xef7a63d0) revert(0x1c, 0x04) } // Cache the free memory pointer let m := mload(0x40) // Store Wrapped Token's `deposit()` function selector: // `bytes4(keccak256("deposit()"))` mstore(0x00, 0xd0e30db0) // Deposit native token in exchange for wrapped native token // Note: using some wrapped tokens' fallback function for deposit allows saving the previous // selector loading into memory to call wrappedToken's `deposit()`. // This is avoided due to some chain's wrapped native versions not allowing such behaviour if iszero( call( gas(), // Remaining amount of gas cachedWrappedToken, // Address of `wrappedToken` callvalue(), // `msg.value` 0x1c, // byte offset in memory where calldata starts 0x24, // size of the calldata to copy 0x00, // byte offset in memory to store the return data 0x00 // size of the return data ) ) { // Throw the `WrappedTokenDepositFailed()` error mstore(0x00, 0x22cd2378) revert(0x1c, 0x04) } // Store MaxApy vault's `deposit()` function selector: // `bytes4(keccak256("deposit(uint256,address)"))` mstore(0x00, 0x6e553f65) mstore(0x20, callvalue()) // Append the `amount` argument mstore(0x40, recipient) // Append the `recipient` argument // Deposit into MaxApy vault if iszero( call( gas(), // Remaining amount of gas cachedVault, // Address of `vault` 0, // `msg.value` 0x1c, // byte offset in memory where calldata starts 0x44, // size of the calldata to copy 0x00, // byte offset in memory to store the return data 0x20 // size of the return data ) ) { // If call failed, throw the error thrown in the previous `call` revert(0x00, 0x04) } // Emit the `DepositNative` event mstore(0x20, callvalue()) log2(0x00, 0x40, _DEPOSIT_NATIVE_EVENT_SIGNATURE, recipient) mstore(0x40, m) // Restore the free memory pointer return(0x00, 0x20) // Return `shares` value stored in 0x00 from previous from call's } } /// @notice Withdraws the calling account's tokens from MaxApy's Vault, redeeming /// amount `shares` for the corresponding amount of tokens, which will be transferred to /// `recipient` in the form of the chain's native token /// @param shares How many shares to try and redeem for tokens /// @param recipient The address to issue the shares from MaxApy's Vault to /// @param maxLoss The maximum acceptable loss to sustain on withdrawal. Up to loss specified amount of shares may be /// burnt to cover losses on withdrawal function withdrawNative(uint256 shares, address recipient, uint256 maxLoss) external returns (uint256) { // Cache `wrappedToken` and `vault` due to assembly's immutable access restrictions address cachedWrappedToken = address(wrappedToken); address cachedVault = address(vault); assembly ("memory-safe") { // Check if `shares` passed by user is `type(uint256).max` if eq(shares, not(0)) { // Store `vault`'s `balanceOf()` function selector: // `bytes4(keccak256("balanceOf(address)"))` mstore(0x00, 0x70a08231) mstore(0x20, caller()) // append the `owner` argument as `msg.sender` // query `vault`'s `msg.sender` `balanceOf()` if iszero( staticcall( gas(), // Remaining amount of gas cachedVault, // Address of `vault` 0x1c, // byte offset in memory where calldata starts 0x24, // size of the calldata to copy 0x00, // byte offset in memory to store the return data 0x20 // size of the return data ) ) { // Revert if balance query fails revert(0x00, 0x04) } // Store `msg.sender`'s balance returned by staticcall into `shares` shares := mload(0x00) } } // Transfer caller shares address(vault).safeTransferFrom(msg.sender, address(this), shares); uint256 amountWithdrawn; assembly ("memory-safe") { // Cache the free memory pointer let m := mload(0x40) // Store `vault`'s `withdraw()` function selector: // `bytes4(keccak256("withdraw(address)"))` mstore(0x00, 0xe63697c8) mstore(0x20, shares) // append the `shares` argument mstore(0x40, address()) // append the `address(this)` argument mstore(0x60, maxLoss) // append the `maxLoss` argument // Withdraw from MaxApy vault if iszero( call( gas(), // Remaining amount of gas cachedVault, // Address of `vault` 0, // `msg.value` 0x1c, // byte offset in memory where calldata starts 0x64, // size of the calldata to copy 0x00, // byte offset in memory to store the return data 0x20 // size of the return data ) ) { // If call failed, throw the error thrown in the previous `call` revert(0x00, 0x04) } // Store `amountWithdrawn` returned by the previous call to `withdraw()` amountWithdrawn := mload(0x00) // Store `wrappedToken`'s `withdraw()` function selector: // `bytes4(keccak256("withdraw(uint256)"))` mstore(0x00, 0x2e1a7d4d) mstore(0x20, amountWithdrawn) // append the `amountWithdrawn` argument // Withdraw from wrapped token if iszero( call( gas(), // Remaining amount of gas cachedWrappedToken, // Address of `vault` 0, // `msg.value` 0x1c, // byte offset in memory where calldata starts 0x24, // size of the calldata to copy 0x00, // byte offset in memory to store the return data 0x20 // size of the return data ) ) { // If call failed, throw the error thrown in the previous `call` revert(0x00, 0x04) } // Transfer native token back to user if iszero(call(gas(), recipient, amountWithdrawn, 0x00, 0x00, 0x00, 0x00)) { // If call failed, throw the `FailedNativeTransfer()` error mstore(0x00, 0x3c3f4130) revert(0x1c, 0x04) } // Emit the `WithdrawNative` event mstore(0x00, shares) mstore(0x20, amountWithdrawn) log2(0x00, 0x40, _WITHDRAW_NATIVE_EVENT_SIGNATURE, recipient) mstore(0x60, 0) // Restore the zero slot mstore(0x40, m) // Restore the free memory pointer return(0x20, 0x20) // Return `amountWithdrawn` value stored in 0x00 from previous from call's } } //////////////////////////////////////////////////////////////// /// RECEIVE() function /// //////////////////////////////////////////////////////////////// /// @notice Receive function to accept native transfers /// @dev Note only the chain's wrapped token will be able to perform native token transfers /// to this contract receive() external payable { // Cache `wrappedToken` due to assembly immutable access restrictions address cachedWrappedToken = address(wrappedToken); assembly { // Check if caller is not the `wrappedToken` if iszero(eq(caller(), cachedWrappedToken)) { // Throw the `ReceiveNotAllowed()` error mstore(0x00, 0xcb263c3f) revert(0x1c, 0x04) } } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; interface IWrappedToken { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; import {StrategyData} from "../helpers/VaultTypes.sol"; /** * @notice MaxApyVault contains the main interface for MaxApy Vaults */ interface IMaxApyVault { /// User-facing vault functions function deposit(uint256 amount, address recipient) external returns (uint256); function withdraw(uint256 shares, address recipient, uint256 maxLoss) external returns (uint256); function report(uint128 gain, uint128 loss, uint128 debtPayment) external returns (uint256); /// ERC20 Token functions function name() external returns (string memory); function symbol() external returns (string memory); function decimals() external returns (uint8); function underlyingAsset() external view returns (address); function totalSupply() external view returns (uint256); function balanceOf(address user) external view returns (uint256); /// Ownership function transferOwnership(address newOwner) external payable; function renounceOwnership() external payable; function requestOwnershipHandover() external payable; function cancelOwnershipHandover() external payable; function completeOwnershipHandover(address pendingOwner) external payable; /// View ownership function ownershipHandoverExpiresAt(address pendingOwner) external view returns (uint256); function ownershipHandoverValidFor() external view returns (uint64); function owner() external view returns (address result); /// Roles function grantRoles(address user, uint256 roles) external payable; function revokeRoles(address user, uint256 roles) external payable; function renounceRoles(uint256 roles) external payable; /// View roles function ADMIN_ROLE() external returns (uint256); function EMERGENCY_ADMIN_ROLE() external returns (uint256); function KEEPER_ROLE() external returns (uint256); function STRATEGY_ROLE() external returns (uint256); function hasAnyRole(address user, uint256 roles) external view returns (bool result); function hasAllRoles(address user, uint256 roles) external view returns (bool result); function rolesOf(address user) external view returns (uint256 roles); function rolesFromOrdinals(uint8[] memory ordinals) external pure returns (uint256 roles); function ordinalsFromRoles(uint256 roles) external pure returns (uint8[] memory ordinals); /// Vault configuration function debtRatio() external returns (uint256); function totalDebt() external returns (uint256); function totalIdle() external returns (uint256); function strategies(address strategy) external returns (StrategyData memory); function withdrawalQueue(uint256 index) external returns (address); function emergencyShutdown() external returns (bool); /// Vault management function setEmergencyShutdown(bool _emergencyShutdown) external; function addStrategy( address newStrategy, uint256 strategyDebtRatio, uint256 strategyMaxDebtPerHarvest, uint256 strategyMinDebtPerHarvest, uint256 strategyPerformanceFee ) external; function revokeStrategy(address strategy) external; function removeStrategy(address strategy) external; function updateStrategyData( address strategy, uint256 newDebtRatio, uint256 newMaxDebtPerHarvest, uint256 newMinDebtPerHarvest, uint256 newPerformanceFee ) external; function setWithdrawalQueue(address[20] calldata queue) external; function setPerformanceFee(uint256 _performanceFee) external; function setManagementFee(uint256 _managementFee) external; function setLockedProfitDegradation(uint256 _lockedProfitDegradation) external; function setDepositLimit(uint256 _depositLimit) external; function setTreasury(address _treasury) external; /// Vault view functions function performanceFee() external returns (uint256); function managementFee() external returns (uint256); function lockedProfitDegradation() external view returns (uint256); function depositLimit() external returns (uint256); function MAXIMUM_STRATEGIES() external returns (uint256); function DEGRADATION_COEFFICIENT() external view returns (uint256); function shareValue(uint256 shares) external view returns (uint256); function sharesForAmount(uint256 amount) external view returns (uint256 shares); function debtOutstanding(address strategy) external view returns (uint256); function totalAssets() external view returns (uint256); function lastReport() external view returns (uint256); function lockedProfit() external view returns (uint256); function treasury() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller. library SafeTransferLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ETH transfer has failed. error ETHTransferFailed(); /// @dev The ERC20 `transferFrom` has failed. error TransferFromFailed(); /// @dev The ERC20 `transfer` has failed. error TransferFailed(); /// @dev The ERC20 `approve` has failed. error ApproveFailed(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Suggested gas stipend for contract receiving ETH /// that disallows any storage writes. uint256 internal constant _GAS_STIPEND_NO_STORAGE_WRITES = 2300; /// @dev Suggested gas stipend for contract receiving ETH to perform a few /// storage reads and writes, but low enough to prevent griefing. /// Multiply by a small constant (e.g. 2), if needed. uint256 internal constant _GAS_STIPEND_NO_GRIEF = 100000; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ETH OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Sends `amount` (in wei) ETH to `to`. /// Reverts upon failure. function safeTransferETH(address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { // Transfer the ETH and check if it succeeded or not. if iszero(call(gas(), to, amount, 0, 0, 0, 0)) { // Store the function selector of `ETHTransferFailed()`. mstore(0x00, 0xb12d13eb) // Revert with (offset, size). revert(0x1c, 0x04) } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`. /// The `gasStipend` can be set to a low enough value to prevent /// storage writes or gas griefing. /// /// If sending via the normal procedure fails, force sends the ETH by /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH. /// /// Reverts if the current contract has insufficient balance. function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal { /// @solidity memory-safe-assembly assembly { // If insufficient balance, revert. if lt(selfbalance(), amount) { // Store the function selector of `ETHTransferFailed()`. mstore(0x00, 0xb12d13eb) // Revert with (offset, size). revert(0x1c, 0x04) } // Transfer the ETH and check if it succeeded or not. if iszero(call(gasStipend, to, amount, 0, 0, 0, 0)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. // We can directly use `SELFDESTRUCT` in the contract creation. // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758 if iszero(create(amount, 0x0b, 0x16)) { // For better gas estimation. if iszero(gt(gas(), 1000000)) { revert(0, 0) } } } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with a gas stipend /// equal to `_GAS_STIPEND_NO_GRIEF`. This gas stipend is a reasonable default /// for 99% of cases and can be overriden with the three-argument version of this /// function if necessary. /// /// If sending via the normal procedure fails, force sends the ETH by /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH. /// /// Reverts if the current contract has insufficient balance. function forceSafeTransferETH(address to, uint256 amount) internal { // Manually inlined because the compiler doesn't inline functions with branches. /// @solidity memory-safe-assembly assembly { // If insufficient balance, revert. if lt(selfbalance(), amount) { // Store the function selector of `ETHTransferFailed()`. mstore(0x00, 0xb12d13eb) // Revert with (offset, size). revert(0x1c, 0x04) } // Transfer the ETH and check if it succeeded or not. if iszero(call(_GAS_STIPEND_NO_GRIEF, to, amount, 0, 0, 0, 0)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. // We can directly use `SELFDESTRUCT` in the contract creation. // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758 if iszero(create(amount, 0x0b, 0x16)) { // For better gas estimation. if iszero(gt(gas(), 1000000)) { revert(0, 0) } } } } } /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`. /// The `gasStipend` can be set to a low enough value to prevent /// storage writes or gas griefing. /// /// Simply use `gasleft()` for `gasStipend` if you don't need a gas stipend. /// /// Note: Does NOT revert upon failure. /// Returns whether the transfer of ETH is successful instead. function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal returns (bool success) { /// @solidity memory-safe-assembly assembly { // Transfer the ETH and check if it succeeded or not. success := call(gasStipend, to, amount, 0, 0, 0, 0) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC20 OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. /// Reverts upon failure. /// /// The `from` account must have at least `amount` approved for /// the current contract to manage. function safeTransferFrom(address token, address from, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, amount) // Store the `amount` argument. mstore(0x40, to) // Store the `to` argument. mstore(0x2c, shl(96, from)) // Store the `from` argument. // Store the function selector of `transferFrom(address,address,uint256)`. mstore(0x0c, 0x23b872dd000000000000000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) ) ) { // Store the function selector of `TransferFromFailed()`. mstore(0x00, 0x7939f424) // Revert with (offset, size). revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot to zero. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Sends all of ERC20 `token` from `from` to `to`. /// Reverts upon failure. /// /// The `from` account must have at least `amount` approved for /// the current contract to manage. function safeTransferAllFrom(address token, address from, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x40, to) // Store the `to` argument. mstore(0x2c, shl(96, from)) // Store the `from` argument. // Store the function selector of `balanceOf(address)`. mstore(0x0c, 0x70a08231000000000000000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20) ) ) { // Store the function selector of `TransferFromFailed()`. mstore(0x00, 0x7939f424) // Revert with (offset, size). revert(0x1c, 0x04) } // Store the function selector of `transferFrom(address,address,uint256)`. mstore(0x00, 0x23b872dd) // The `amount` argument is already written to the memory word at 0x6c. amount := mload(0x60) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) ) ) { // Store the function selector of `TransferFromFailed()`. mstore(0x00, 0x7939f424) // Revert with (offset, size). revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot to zero. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. /// Reverts upon failure. function safeTransfer(address token, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { mstore(0x14, to) // Store the `to` argument. mstore(0x34, amount) // Store the `amount` argument. // Store the function selector of `transfer(address,uint256)`. mstore(0x00, 0xa9059cbb000000000000000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { // Store the function selector of `TransferFailed()`. mstore(0x00, 0x90b8ec18) // Revert with (offset, size). revert(0x1c, 0x04) } // Restore the part of the free memory pointer that was overwritten. mstore(0x34, 0) } } /// @dev Sends all of ERC20 `token` from the current contract to `to`. /// Reverts upon failure. function safeTransferAll(address token, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. mstore(0x20, address()) // Store the address of the current contract. if iszero( and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20) ) ) { // Store the function selector of `TransferFailed()`. mstore(0x00, 0x90b8ec18) // Revert with (offset, size). revert(0x1c, 0x04) } mstore(0x14, to) // Store the `to` argument. // The `amount` argument is already written to the memory word at 0x34. amount := mload(0x34) // Store the function selector of `transfer(address,uint256)`. mstore(0x00, 0xa9059cbb000000000000000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { // Store the function selector of `TransferFailed()`. mstore(0x00, 0x90b8ec18) // Revert with (offset, size). revert(0x1c, 0x04) } // Restore the part of the free memory pointer that was overwritten. mstore(0x34, 0) } } /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. /// Reverts upon failure. function safeApprove(address token, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { mstore(0x14, to) // Store the `to` argument. mstore(0x34, amount) // Store the `amount` argument. // Store the function selector of `approve(address,uint256)`. mstore(0x00, 0x095ea7b3000000000000000000000000) if iszero( and( // The arguments of `and` are evaluated from right to left. // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(eq(mload(0x00), 1), iszero(returndatasize())), call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { // Store the function selector of `ApproveFailed()`. mstore(0x00, 0x3e3f8f73) // Revert with (offset, size). revert(0x1c, 0x04) } // Restore the part of the free memory pointer that was overwritten. mstore(0x34, 0) } } /// @dev Returns the amount of ERC20 `token` owned by `account`. /// Returns zero if the `token` does not exist. function balanceOf(address token, address account) internal view returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x14, account) // Store the `account` argument. // Store the function selector of `balanceOf(address)`. mstore(0x00, 0x70a08231000000000000000000000000) amount := mul( mload(0x20), and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20) ) ) } } }
pragma solidity ^0.8.19; /// @notice Stores all data from a single strategy /// @dev Packed in two slots struct StrategyData { /// Slot 0 /// @notice Maximum percentage available to be lent to strategies(in BPS) /// @dev in BPS. uint16 is enough to cover the max BPS value of 10_000 uint16 strategyDebtRatio; /// @notice The performance fee /// @dev in BPS. uint16 is enough to cover the max BPS value of 10_000 uint16 strategyPerformanceFee; /// @notice Timestamp when the strategy was added. /// @dev Overflowing July 21, 2554 uint48 strategyActivation; /// @notice block.timestamp of the last time a report occured /// @dev Overflowing July 21, 2554 uint48 strategyLastReport; /// @notice Upper limit on the increase of debt since last harvest /// @dev max debt per harvest to be set to a maximum value of 4,722,366,482,869,645,213,695 uint128 strategyMaxDebtPerHarvest; /// Slot 1 /// @notice Lower limit on the increase of debt since last harvest /// @dev min debt per harvest to be set to a maximum value of 16,777,215 uint128 strategyMinDebtPerHarvest; /// @notice Total returns that Strategy has realized for Vault /// @dev max strategy total gain of 79,228,162,514,264,337,593,543,950,335 uint128 strategyTotalGain; /// Slot 2 /// @notice Total outstanding debt that Strategy has /// @dev max total debt of 79,228,162,514,264,337,593,543,950,335 uint128 strategyTotalDebt; /// @notice Total losses that Strategy has realized for Vault /// @dev max strategy total loss of 79,228,162,514,264,337,593,543,950,335 uint128 strategyTotalLoss; }
{ "remappings": [ "solady/=lib/solady/src/", "openzeppelin/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IWrappedToken","name":"_wrappedToken","type":"address"},{"internalType":"contract IMaxApyVault","name":"_vault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"FailedNativeTransfer","type":"error"},{"inputs":[],"name":"InvalidZeroValue","type":"error"},{"inputs":[],"name":"ReceiveNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositNative","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawNative","type":"event"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"depositNative","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IMaxApyVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"maxLoss","type":"uint256"}],"name":"withdrawNative","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrappedToken","outputs":[{"internalType":"contract IWrappedToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c060405234801561001057600080fd5b506040516105c33803806105c383398101604081905261002f916100c0565b6001600160a01b03808316608081905290821660a0526100529082600019610059565b50506100fa565b81601452806034526f095ea7b300000000000000000000000060005260206000604460106000875af13d15600160005114171661009e57633e3f8f736000526004601cfd5b6000603452505050565b6001600160a01b03811681146100bd57600080fd5b50565b600080604083850312156100d357600080fd5b82516100de816100a8565b60208401519092506100ef816100a8565b809150509250929050565b60805160a05161047c61014760003960008181610129015281816101700152818161024b01526102a6015260008181604a0152818160dd0152818161014f015261022a015261047c6000f3fe6080604052600436106100435760003560e01c806333bb7f91146100855780633f2aecb2146100ab578063996c6cc3146100cb578063fbfa77cf1461011757600080fd5b36610080577f000000000000000000000000000000000000000000000000000000000000000033811461007e5763cb263c3f6000526004601cfd5b005b600080fd5b6100986100933660046103ef565b61014b565b6040519081526020015b60405180910390f35b3480156100b757600080fd5b506100986100c6366004610411565b610226565b3480156100d757600080fd5b506100ff7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100a2565b34801561012357600080fd5b506100ff7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000346101a25763ef7a63d06000526004601cfd5b60405163d0e30db06000526000806024601c34875af16101ca576322cd23786000526004601cfd5b636e553f656000523460205284604052602060006044601c6000865af16101f15760046000fd5b34602052847f6bb902f8baf2580ae3dae24e58f4b874ecca85152076af921bfd172dce1c7e2860406000a28060405260206000f35b60007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060018601610299576370a0823160005233602052602060006024601c845afa6102935760046000fd5b60005195505b6102ce6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308961037f565b600060405163e63697c8600052876020523060405285606052602060006064601c6000875af16102fe5760046000fd5b6000519150632e1a7d4d60005281602052602060006024601c6000885af16103265760046000fd5b600080600080858b5af161034257633c3f41306000526004601cfd5b8760005281602052867f5cb35f4e7dbc40dd34f0d58cec4f5548fc47638cb46d7964e4f07c48e97e4c7d60406000a2600060605280604052602080f35b60405181606052826040528360601b602c526323b872dd60601b600c52602060006064601c6000895af13d1560016000511417166103c557637939f4246000526004601cfd5b600060605260405250505050565b80356001600160a01b03811681146103ea57600080fd5b919050565b60006020828403121561040157600080fd5b61040a826103d3565b9392505050565b60008060006060848603121561042657600080fd5b83359250610436602085016103d3565b915060408401359050925092509256fea2646970667358221220e5c2ab65123540ff97b5bef75ddaab15204556dbf5b8bb24e687a69fa593b55564736f6c63430008130033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000005da197c9bc9cfc36cd35c5f49954eae7527604c3
Deployed Bytecode
0x6080604052600436106100435760003560e01c806333bb7f91146100855780633f2aecb2146100ab578063996c6cc3146100cb578063fbfa77cf1461011757600080fd5b36610080577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc233811461007e5763cb263c3f6000526004601cfd5b005b600080fd5b6100986100933660046103ef565b61014b565b6040519081526020015b60405180910390f35b3480156100b757600080fd5b506100986100c6366004610411565b610226565b3480156100d757600080fd5b506100ff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040516001600160a01b0390911681526020016100a2565b34801561012357600080fd5b506100ff7f0000000000000000000000005da197c9bc9cfc36cd35c5f49954eae7527604c381565b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000005da197c9bc9cfc36cd35c5f49954eae7527604c3346101a25763ef7a63d06000526004601cfd5b60405163d0e30db06000526000806024601c34875af16101ca576322cd23786000526004601cfd5b636e553f656000523460205284604052602060006044601c6000865af16101f15760046000fd5b34602052847f6bb902f8baf2580ae3dae24e58f4b874ecca85152076af921bfd172dce1c7e2860406000a28060405260206000f35b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f0000000000000000000000005da197c9bc9cfc36cd35c5f49954eae7527604c360018601610299576370a0823160005233602052602060006024601c845afa6102935760046000fd5b60005195505b6102ce6001600160a01b037f0000000000000000000000005da197c9bc9cfc36cd35c5f49954eae7527604c31633308961037f565b600060405163e63697c8600052876020523060405285606052602060006064601c6000875af16102fe5760046000fd5b6000519150632e1a7d4d60005281602052602060006024601c6000885af16103265760046000fd5b600080600080858b5af161034257633c3f41306000526004601cfd5b8760005281602052867f5cb35f4e7dbc40dd34f0d58cec4f5548fc47638cb46d7964e4f07c48e97e4c7d60406000a2600060605280604052602080f35b60405181606052826040528360601b602c526323b872dd60601b600c52602060006064601c6000895af13d1560016000511417166103c557637939f4246000526004601cfd5b600060605260405250505050565b80356001600160a01b03811681146103ea57600080fd5b919050565b60006020828403121561040157600080fd5b61040a826103d3565b9392505050565b60008060006060848603121561042657600080fd5b83359250610436602085016103d3565b915060408401359050925092509256fea2646970667358221220e5c2ab65123540ff97b5bef75ddaab15204556dbf5b8bb24e687a69fa593b55564736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000005da197c9bc9cfc36cd35c5f49954eae7527604c3
-----Decoded View---------------
Arg [0] : _wrappedToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : _vault (address): 0x5Da197c9BC9cFC36Cd35C5F49954eaE7527604C3
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 0000000000000000000000005da197c9bc9cfc36cd35c5f49954eae7527604c3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.