Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
119387183 | 229 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ActionCallbackV3
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "../interfaces/IPActionCallbackV3.sol"; import "../core/libraries/Errors.sol"; import "./base/CallbackHelper.sol"; import "../core/libraries/TokenHelper.sol"; contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelper, TokenHelper { using PMath for int256; using PMath for uint256; using PYIndexLib for PYIndex; using PYIndexLib for IPYieldToken; function swapCallback(int256 ptToAccount, int256 syToAccount, bytes calldata data) external override { ActionType swapType = _getActionType(data); if (swapType == ActionType.SwapExactSyForYt) { _callbackSwapExactSyForYt(ptToAccount, syToAccount, data); } else if (swapType == ActionType.SwapYtForSy) { _callbackSwapYtForSy(ptToAccount, syToAccount, data); } else if (swapType == ActionType.SwapExactYtForPt) { _callbackSwapExactYtForPt(ptToAccount, syToAccount, data); } else if (swapType == ActionType.SwapExactPtForYt) { _callbackSwapExactPtForYt(ptToAccount, syToAccount, data); } else { assert(false); } } function limitRouterCallback( uint256 actualMaking, uint256 actualTaking, uint256 totalFee, bytes memory data ) external returns ( bytes memory // encode as netTransferToLimit, netOutputFromLimit ) { bool isEmptyFill = (actualMaking == 0 && actualTaking == 0 && totalFee == 0); if (isEmptyFill) { return abi.encode(0, 0); } (OrderType orderType, IPYieldToken YT, uint256 netRemaining, address receiver) = abi.decode( data, (OrderType, IPYieldToken, uint256, address) ); if (orderType == OrderType.SY_FOR_PT || orderType == OrderType.SY_FOR_YT) { PYIndex index = YT.newIndex(); uint256 totalSyToMintPy = index.assetToSyUp(actualTaking); uint256 additionalSyToMint = totalSyToMintPy - actualMaking; require(additionalSyToMint <= netRemaining, "Slippage: INSUFFICIENT_SY_LIMIT"); _transferOut(YT.SY(), address(YT), additionalSyToMint); uint256 netPyToReceiver; if (orderType == OrderType.SY_FOR_PT) { netPyToReceiver = YT.mintPY(address(this), receiver); _safeApproveInf(YT.PT(), msg.sender); } else { netPyToReceiver = YT.mintPY(receiver, address(this)); _safeApproveInf(address(YT), msg.sender); } return abi.encode(additionalSyToMint, netPyToReceiver); } else { require(actualMaking <= netRemaining, "Slippage: INSUFFICIENT_PY_LIMIT"); if (orderType == OrderType.PT_FOR_SY) { _transferOut(address(YT), address(YT), actualMaking); } else { _transferOut(YT.PT(), address(YT), actualMaking); } uint256 netSyRedeemed = IPYieldToken(YT).redeemPY(address(this)); require(actualTaking <= netSyRedeemed, "Slippage: INSUFFICIENT_PY_REDEEM"); uint256 netSyToReceiver = netSyRedeemed - actualTaking; address SY = YT.SY(); _transferOut(SY, receiver, netSyToReceiver); _safeApproveInf(SY, msg.sender); return abi.encode(actualMaking, netSyToReceiver); } } function _callbackSwapExactSyForYt(int256 ptToAccount, int256, /*syToAccount*/ bytes calldata data) internal { (address receiver, IPYieldToken YT) = _decodeSwapExactSyForYt(data); uint256 ptOwed = ptToAccount.abs(); uint256 netPyOut = YT.mintPY(msg.sender, receiver); if (netPyOut < ptOwed) revert("Slippage: INSUFFICIENT_PT_REPAY"); } function _callbackSwapYtForSy(int256 ptToAccount, int256 syToAccount, bytes calldata data) internal { (address receiver, IPYieldToken YT) = _decodeSwapYtForSy(data); PYIndex pyIndex = YT.newIndex(); uint256 syOwed = syToAccount.neg().Uint(); address[] memory receivers = new address[](2); uint256[] memory amountPYToRedeems = new uint256[](2); (receivers[0], amountPYToRedeems[0]) = (msg.sender, pyIndex.syToAssetUp(syOwed)); (receivers[1], amountPYToRedeems[1]) = (receiver, ptToAccount.Uint() - amountPYToRedeems[0]); YT.redeemPYMulti(receivers, amountPYToRedeems); } function _callbackSwapExactPtForYt(int256 ptToAccount, int256, /*syToAccount*/ bytes calldata data) internal { (address receiver, uint256 exactPtIn, uint256 minYtOut, IPYieldToken YT) = _decodeSwapExactPtForYt(data); uint256 netPtOwed = ptToAccount.abs(); uint256 netPyOut = YT.mintPY(msg.sender, receiver); if (netPyOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT"); if (exactPtIn + netPyOut < netPtOwed) revert("Slippage: INSUFFICIENT_PT_REPAY"); } function _callbackSwapExactYtForPt(int256 ptToAccount, int256 syToAccount, bytes calldata data) internal { (address receiver, uint256 netPtOut, IPPrincipalToken PT, IPYieldToken YT) = _decodeSwapExactYtForPt(data); uint256 netSyOwed = syToAccount.abs(); uint256 netPtRedeemSy = ptToAccount.Uint() - netPtOut; _transferOut(address(PT), address(YT), netPtRedeemSy); uint256 netSyToMarket = YT.redeemPY(msg.sender); if (netSyToMarket < netSyOwed) revert("Slippage: INSUFFICIENT_SY_REPAY"); _transferOut(address(PT), receiver, netPtOut); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; library Errors { // BulkSeller error BulkInsufficientSyForTrade(uint256 currentAmount, uint256 requiredAmount); error BulkInsufficientTokenForTrade(uint256 currentAmount, uint256 requiredAmount); error BulkInSufficientSyOut(uint256 actualSyOut, uint256 requiredSyOut); error BulkInSufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut); error BulkInsufficientSyReceived(uint256 actualBalance, uint256 requiredBalance); error BulkNotMaintainer(); error BulkNotAdmin(); error BulkSellerAlreadyExisted(address token, address SY, address bulk); error BulkSellerInvalidToken(address token, address SY); error BulkBadRateTokenToSy(uint256 actualRate, uint256 currentRate, uint256 eps); error BulkBadRateSyToToken(uint256 actualRate, uint256 currentRate, uint256 eps); // APPROX error ApproxFail(); error ApproxParamsInvalid(uint256 guessMin, uint256 guessMax, uint256 eps); error ApproxBinarySearchInputInvalid( uint256 approxGuessMin, uint256 approxGuessMax, uint256 minGuessMin, uint256 maxGuessMax ); // MARKET + MARKET MATH CORE error MarketExpired(); error MarketZeroAmountsInput(); error MarketZeroAmountsOutput(); error MarketZeroLnImpliedRate(); error MarketInsufficientPtForTrade(int256 currentAmount, int256 requiredAmount); error MarketInsufficientPtReceived(uint256 actualBalance, uint256 requiredBalance); error MarketInsufficientSyReceived(uint256 actualBalance, uint256 requiredBalance); error MarketZeroTotalPtOrTotalAsset(int256 totalPt, int256 totalAsset); error MarketExchangeRateBelowOne(int256 exchangeRate); error MarketProportionMustNotEqualOne(); error MarketRateScalarBelowZero(int256 rateScalar); error MarketScalarRootBelowZero(int256 scalarRoot); error MarketProportionTooHigh(int256 proportion, int256 maxProportion); error OracleUninitialized(); error OracleTargetTooOld(uint32 target, uint32 oldest); error OracleZeroCardinality(); error MarketFactoryExpiredPt(); error MarketFactoryInvalidPt(); error MarketFactoryMarketExists(); error MarketFactoryLnFeeRateRootTooHigh(uint80 lnFeeRateRoot, uint256 maxLnFeeRateRoot); error MarketFactoryOverriddenFeeTooHigh(uint80 overriddenFee, uint256 marketLnFeeRateRoot); error MarketFactoryReserveFeePercentTooHigh(uint8 reserveFeePercent, uint8 maxReserveFeePercent); error MarketFactoryZeroTreasury(); error MarketFactoryInitialAnchorTooLow(int256 initialAnchor, int256 minInitialAnchor); error MFNotPendleMarket(address addr); // ROUTER error RouterInsufficientLpOut(uint256 actualLpOut, uint256 requiredLpOut); error RouterInsufficientSyOut(uint256 actualSyOut, uint256 requiredSyOut); error RouterInsufficientPtOut(uint256 actualPtOut, uint256 requiredPtOut); error RouterInsufficientYtOut(uint256 actualYtOut, uint256 requiredYtOut); error RouterInsufficientPYOut(uint256 actualPYOut, uint256 requiredPYOut); error RouterInsufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut); error RouterInsufficientSyRepay(uint256 actualSyRepay, uint256 requiredSyRepay); error RouterInsufficientPtRepay(uint256 actualPtRepay, uint256 requiredPtRepay); error RouterNotAllSyUsed(uint256 netSyDesired, uint256 netSyUsed); error RouterTimeRangeZero(); error RouterCallbackNotPendleMarket(address caller); error RouterInvalidAction(bytes4 selector); error RouterInvalidFacet(address facet); error RouterKyberSwapDataZero(); error SimulationResults(bool success, bytes res); // YIELD CONTRACT error YCExpired(); error YCNotExpired(); error YieldContractInsufficientSy(uint256 actualSy, uint256 requiredSy); error YCNothingToRedeem(); error YCPostExpiryDataNotSet(); error YCNoFloatingSy(); // YieldFactory error YCFactoryInvalidExpiry(); error YCFactoryYieldContractExisted(); error YCFactoryZeroExpiryDivisor(); error YCFactoryZeroTreasury(); error YCFactoryInterestFeeRateTooHigh(uint256 interestFeeRate, uint256 maxInterestFeeRate); error YCFactoryRewardFeeRateTooHigh(uint256 newRewardFeeRate, uint256 maxRewardFeeRate); // SY error SYInvalidTokenIn(address token); error SYInvalidTokenOut(address token); error SYZeroDeposit(); error SYZeroRedeem(); error SYInsufficientSharesOut(uint256 actualSharesOut, uint256 requiredSharesOut); error SYInsufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut); // SY-specific error SYQiTokenMintFailed(uint256 errCode); error SYQiTokenRedeemFailed(uint256 errCode); error SYQiTokenRedeemRewardsFailed(uint256 rewardAccruedType0, uint256 rewardAccruedType1); error SYQiTokenBorrowRateTooHigh(uint256 borrowRate, uint256 borrowRateMax); error SYCurveInvalidPid(); error SYCurve3crvPoolNotFound(); error SYApeDepositAmountTooSmall(uint256 amountDeposited); error SYBalancerInvalidPid(); error SYInvalidRewardToken(address token); error SYStargateRedeemCapExceeded(uint256 amountLpDesired, uint256 amountLpRedeemable); error SYBalancerReentrancy(); error NotFromTrustedRemote(uint16 srcChainId, bytes path); error ApxETHNotEnoughBuffer(); // Liquidity Mining error VCInactivePool(address pool); error VCPoolAlreadyActive(address pool); error VCZeroVePendle(address user); error VCExceededMaxWeight(uint256 totalWeight, uint256 maxWeight); error VCEpochNotFinalized(uint256 wTime); error VCPoolAlreadyAddAndRemoved(address pool); error VEInvalidNewExpiry(uint256 newExpiry); error VEExceededMaxLockTime(); error VEInsufficientLockTime(); error VENotAllowedReduceExpiry(); error VEZeroAmountLocked(); error VEPositionNotExpired(); error VEZeroPosition(); error VEZeroSlope(uint128 bias, uint128 slope); error VEReceiveOldSupply(uint256 msgTime); error GCNotPendleMarket(address caller); error GCNotVotingController(address caller); error InvalidWTime(uint256 wTime); error ExpiryInThePast(uint256 expiry); error ChainNotSupported(uint256 chainId); error FDTotalAmountFundedNotMatch(uint256 actualTotalAmount, uint256 expectedTotalAmount); error FDEpochLengthMismatch(); error FDInvalidPool(address pool); error FDPoolAlreadyExists(address pool); error FDInvalidNewFinishedEpoch(uint256 oldFinishedEpoch, uint256 newFinishedEpoch); error FDInvalidStartEpoch(uint256 startEpoch); error FDInvalidWTimeFund(uint256 lastFunded, uint256 wTime); error FDFutureFunding(uint256 lastFunded, uint256 currentWTime); error BDInvalidEpoch(uint256 epoch, uint256 startTime); // Cross-Chain error MsgNotFromSendEndpoint(uint16 srcChainId, bytes path); error MsgNotFromReceiveEndpoint(address sender); error InsufficientFeeToSendMsg(uint256 currentFee, uint256 requiredFee); error ApproxDstExecutionGasNotSet(); error InvalidRetryData(); // GENERIC MSG error ArrayLengthMismatch(); error ArrayEmpty(); error ArrayOutOfBounds(); error ZeroAddress(); error FailedToSendEther(); error InvalidMerkleProof(); error OnlyLayerZeroEndpoint(); error OnlyYT(); error OnlyYCFactory(); error OnlyWhitelisted(); // Swap Aggregator error SAInsufficientTokenIn(address tokenIn, uint256 amountExpected, uint256 amountActual); error UnsupportedSelector(uint256 aggregatorType, bytes4 selector); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; /* solhint-disable private-vars-leading-underscore, reason-string */ library PMath { uint256 internal constant ONE = 1e18; // 18 decimal places int256 internal constant IONE = 1e18; // 18 decimal places function subMax0(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { return (a >= b ? a - b : 0); } } function subNoNeg(int256 a, int256 b) internal pure returns (int256) { require(a >= b, "negative"); return a - b; // no unchecked since if b is very negative, a - b might overflow } function mulDown(uint256 a, uint256 b) internal pure returns (uint256) { uint256 product = a * b; unchecked { return product / ONE; } } function mulDown(int256 a, int256 b) internal pure returns (int256) { int256 product = a * b; unchecked { return product / IONE; } } function divDown(uint256 a, uint256 b) internal pure returns (uint256) { uint256 aInflated = a * ONE; unchecked { return aInflated / b; } } function divDown(int256 a, int256 b) internal pure returns (int256) { int256 aInflated = a * IONE; unchecked { return aInflated / b; } } function rawDivUp(uint256 a, uint256 b) internal pure returns (uint256) { return (a + b - 1) / b; } // @author Uniswap function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } function square(uint256 x) internal pure returns (uint256) { return x * x; } function squareDown(uint256 x) internal pure returns (uint256) { return mulDown(x, x); } function abs(int256 x) internal pure returns (uint256) { return uint256(x > 0 ? x : -x); } function neg(int256 x) internal pure returns (int256) { return x * (-1); } function neg(uint256 x) internal pure returns (int256) { return Int(x) * (-1); } function max(uint256 x, uint256 y) internal pure returns (uint256) { return (x > y ? x : y); } function max(int256 x, int256 y) internal pure returns (int256) { return (x > y ? x : y); } function min(uint256 x, uint256 y) internal pure returns (uint256) { return (x < y ? x : y); } function min(int256 x, int256 y) internal pure returns (int256) { return (x < y ? x : y); } /*/////////////////////////////////////////////////////////////// SIGNED CASTS //////////////////////////////////////////////////////////////*/ function Int(uint256 x) internal pure returns (int256) { require(x <= uint256(type(int256).max)); return int256(x); } function Int128(int256 x) internal pure returns (int128) { require(type(int128).min <= x && x <= type(int128).max); return int128(x); } function Int128(uint256 x) internal pure returns (int128) { return Int128(Int(x)); } /*/////////////////////////////////////////////////////////////// UNSIGNED CASTS //////////////////////////////////////////////////////////////*/ function Uint(int256 x) internal pure returns (uint256) { require(x >= 0); return uint256(x); } function Uint32(uint256 x) internal pure returns (uint32) { require(x <= type(uint32).max); return uint32(x); } function Uint64(uint256 x) internal pure returns (uint64) { require(x <= type(uint64).max); return uint64(x); } function Uint112(uint256 x) internal pure returns (uint112) { require(x <= type(uint112).max); return uint112(x); } function Uint96(uint256 x) internal pure returns (uint96) { require(x <= type(uint96).max); return uint96(x); } function Uint128(uint256 x) internal pure returns (uint128) { require(x <= type(uint128).max); return uint128(x); } function Uint192(uint256 x) internal pure returns (uint192) { require(x <= type(uint192).max); return uint192(x); } function isAApproxB(uint256 a, uint256 b, uint256 eps) internal pure returns (bool) { return mulDown(b, ONE - eps) <= a && a <= mulDown(b, ONE + eps); } function isAGreaterApproxB(uint256 a, uint256 b, uint256 eps) internal pure returns (bool) { return a >= b && a <= mulDown(b, ONE + eps); } function isASmallerApproxB(uint256 a, uint256 b, uint256 eps) internal pure returns (bool) { return a <= b && a >= mulDown(b, ONE - eps); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../../interfaces/IWETH.sol"; abstract contract TokenHelper { using SafeERC20 for IERC20; address internal constant NATIVE = address(0); uint256 internal constant LOWER_BOUND_APPROVAL = type(uint96).max / 2; // some tokens use 96 bits for approval function _transferIn(address token, address from, uint256 amount) internal { if (token == NATIVE) require(msg.value == amount, "eth mismatch"); else if (amount != 0) IERC20(token).safeTransferFrom(from, address(this), amount); } function _transferFrom(IERC20 token, address from, address to, uint256 amount) internal { if (amount != 0) token.safeTransferFrom(from, to, amount); } function _transferOut(address token, address to, uint256 amount) internal { if (amount == 0) return; if (token == NATIVE) { (bool success, ) = to.call{value: amount}(""); require(success, "eth send failed"); } else { IERC20(token).safeTransfer(to, amount); } } function _transferOut(address[] memory tokens, address to, uint256[] memory amounts) internal { uint256 numTokens = tokens.length; require(numTokens == amounts.length, "length mismatch"); for (uint256 i = 0; i < numTokens; ) { _transferOut(tokens[i], to, amounts[i]); unchecked { i++; } } } function _selfBalance(address token) internal view returns (uint256) { return (token == NATIVE) ? address(this).balance : IERC20(token).balanceOf(address(this)); } function _selfBalance(IERC20 token) internal view returns (uint256) { return token.balanceOf(address(this)); } /// @notice Approves the stipulated contract to spend the given allowance in the given token /// @dev PLS PAY ATTENTION to tokens that requires the approval to be set to 0 before changing it function _safeApprove(address token, address to, uint256 value) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "Safe Approve"); } function _safeApproveInf(address token, address to) internal { if (token == NATIVE) return; if (IERC20(token).allowance(address(this), to) < LOWER_BOUND_APPROVAL) { _safeApprove(token, to, 0); _safeApprove(token, to, type(uint256).max); } } function _wrap_unwrap_ETH(address tokenIn, address tokenOut, uint256 netTokenIn) internal { if (tokenIn == NATIVE) IWETH(tokenOut).deposit{value: netTokenIn}(); else IWETH(tokenIn).withdraw(netTokenIn); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "../../interfaces/IPYieldToken.sol"; import "../../interfaces/IPPrincipalToken.sol"; import "./SYUtils.sol"; import "../libraries/math/PMath.sol"; type PYIndex is uint256; library PYIndexLib { using PMath for uint256; using PMath for int256; function newIndex(IPYieldToken YT) internal returns (PYIndex) { return PYIndex.wrap(YT.pyIndexCurrent()); } function syToAsset(PYIndex index, uint256 syAmount) internal pure returns (uint256) { return SYUtils.syToAsset(PYIndex.unwrap(index), syAmount); } function assetToSy(PYIndex index, uint256 assetAmount) internal pure returns (uint256) { return SYUtils.assetToSy(PYIndex.unwrap(index), assetAmount); } function assetToSyUp(PYIndex index, uint256 assetAmount) internal pure returns (uint256) { return SYUtils.assetToSyUp(PYIndex.unwrap(index), assetAmount); } function syToAssetUp(PYIndex index, uint256 syAmount) internal pure returns (uint256) { uint256 _index = PYIndex.unwrap(index); return SYUtils.syToAssetUp(_index, syAmount); } function syToAsset(PYIndex index, int256 syAmount) internal pure returns (int256) { int256 sign = syAmount < 0 ? int256(-1) : int256(1); return sign * (SYUtils.syToAsset(PYIndex.unwrap(index), syAmount.abs())).Int(); } function assetToSy(PYIndex index, int256 assetAmount) internal pure returns (int256) { int256 sign = assetAmount < 0 ? int256(-1) : int256(1); return sign * (SYUtils.assetToSy(PYIndex.unwrap(index), assetAmount.abs())).Int(); } function assetToSyUp(PYIndex index, int256 assetAmount) internal pure returns (int256) { int256 sign = assetAmount < 0 ? int256(-1) : int256(1); return sign * (SYUtils.assetToSyUp(PYIndex.unwrap(index), assetAmount.abs())).Int(); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; library SYUtils { uint256 internal constant ONE = 1e18; function syToAsset(uint256 exchangeRate, uint256 syAmount) internal pure returns (uint256) { return (syAmount * exchangeRate) / ONE; } function syToAssetUp(uint256 exchangeRate, uint256 syAmount) internal pure returns (uint256) { return (syAmount * exchangeRate + ONE - 1) / ONE; } function assetToSy(uint256 exchangeRate, uint256 assetAmount) internal pure returns (uint256) { return (assetAmount * ONE) / exchangeRate; } function assetToSyUp(uint256 exchangeRate, uint256 assetAmount) internal pure returns (uint256) { return (assetAmount * ONE + exchangeRate - 1) / exchangeRate; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "./IPMarketSwapCallback.sol"; import "./IPLimitRouter.sol"; interface IPActionCallbackV3 is IPMarketSwapCallback, IPLimitRouterCallback {}
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; interface IPInterestManagerYT { event CollectInterestFee(uint256 amountInterestFee); function userInterest(address user) external view returns (uint128 lastPYIndex, uint128 accruedInterest); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "../core/StandardizedYield/PYIndex.sol"; interface IPLimitOrderType { enum OrderType { SY_FOR_PT, PT_FOR_SY, SY_FOR_YT, YT_FOR_SY } // Fixed-size order part with core information struct StaticOrder { uint256 salt; uint256 expiry; uint256 nonce; OrderType orderType; address token; address YT; address maker; address receiver; uint256 makingAmount; uint256 lnImpliedRate; uint256 failSafeRate; } struct FillResults { uint256 totalMaking; uint256 totalTaking; uint256 totalFee; uint256 totalNotionalVolume; uint256[] netMakings; uint256[] netTakings; uint256[] netFees; uint256[] notionalVolumes; } } struct Order { uint256 salt; uint256 expiry; uint256 nonce; IPLimitOrderType.OrderType orderType; address token; address YT; address maker; address receiver; uint256 makingAmount; uint256 lnImpliedRate; uint256 failSafeRate; bytes permit; } struct FillOrderParams { Order order; bytes signature; uint256 makingAmount; } interface IPLimitRouterCallback is IPLimitOrderType { function limitRouterCallback( uint256 actualMaking, uint256 actualTaking, uint256 totalFee, bytes memory data ) external returns (bytes memory); } interface IPLimitRouter is IPLimitOrderType { struct OrderStatus { uint128 filledAmount; uint128 remaining; } event OrderCanceled(address indexed maker, bytes32 indexed orderHash); event OrderFilledV2( bytes32 indexed orderHash, OrderType indexed orderType, address indexed YT, address token, uint256 netInputFromMaker, uint256 netOutputToMaker, uint256 feeAmount, uint256 notionalVolume, address maker, address taker ); // @dev actualMaking, actualTaking are in the SY form function fill( FillOrderParams[] memory params, address receiver, uint256 maxTaking, bytes calldata optData, bytes calldata callback ) external returns (uint256 actualMaking, uint256 actualTaking, uint256 totalFee, bytes memory callbackReturn); function feeRecipient() external view returns (address); function hashOrder(Order memory order) external view returns (bytes32); function cancelSingle(Order calldata order) external; function cancelBatch(Order[] calldata orders) external; function orderStatusesRaw( bytes32[] memory orderHashes ) external view returns (uint256[] memory remainingsRaw, uint256[] memory filledAmounts); function orderStatuses( bytes32[] memory orderHashes ) external view returns (uint256[] memory remainings, uint256[] memory filledAmounts); function DOMAIN_SEPARATOR() external view returns (bytes32); function simulate(address target, bytes calldata data) external payable; /* --- Deprecated events --- */ // deprecate on 7/1/2024, prior to official launch event OrderFilled( bytes32 indexed orderHash, OrderType indexed orderType, address indexed YT, address token, uint256 netInputFromMaker, uint256 netOutputToMaker, uint256 feeAmount, uint256 notionalVolume ); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; interface IPMarketSwapCallback { function swapCallback(int256 ptToAccount, int256 syToAccount, bytes calldata data) external; }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; interface IPPrincipalToken is IERC20Metadata { function burnByYT(address user, uint256 amount) external; function mintByYT(address user, uint256 amount) external; function initialize(address _YT) external; function SY() external view returns (address); function YT() external view returns (address); function factory() external view returns (address); function expiry() external view returns (uint256); function isExpired() external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "./IRewardManager.sol"; import "./IPInterestManagerYT.sol"; interface IPYieldToken is IERC20Metadata, IRewardManager, IPInterestManagerYT { event NewInterestIndex(uint256 indexed newIndex); event Mint( address indexed caller, address indexed receiverPT, address indexed receiverYT, uint256 amountSyToMint, uint256 amountPYOut ); event Burn(address indexed caller, address indexed receiver, uint256 amountPYToRedeem, uint256 amountSyOut); event RedeemRewards(address indexed user, uint256[] amountRewardsOut); event RedeemInterest(address indexed user, uint256 interestOut); event CollectRewardFee(address indexed rewardToken, uint256 amountRewardFee); function mintPY(address receiverPT, address receiverYT) external returns (uint256 amountPYOut); function redeemPY(address receiver) external returns (uint256 amountSyOut); function redeemPYMulti( address[] calldata receivers, uint256[] calldata amountPYToRedeems ) external returns (uint256[] memory amountSyOuts); function redeemDueInterestAndRewards( address user, bool redeemInterest, bool redeemRewards ) external returns (uint256 interestOut, uint256[] memory rewardsOut); function rewardIndexesCurrent() external returns (uint256[] memory); function pyIndexCurrent() external returns (uint256); function pyIndexStored() external view returns (uint256); function getRewardTokens() external view returns (address[] memory); function SY() external view returns (address); function PT() external view returns (address); function factory() external view returns (address); function expiry() external view returns (uint256); function isExpired() external view returns (bool); function doCacheIndexSameBlock() external view returns (bool); function pyIndexLastUpdatedBlock() external view returns (uint128); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; interface IRewardManager { function userReward(address token, address user) external view returns (uint128 index, uint128 accrued); }
// SPDX-License-Identifier: GPL-3.0-or-later /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; interface IStandardizedYield is IERC20Metadata { /// @dev Emitted when any base tokens is deposited to mint shares event Deposit( address indexed caller, address indexed receiver, address indexed tokenIn, uint256 amountDeposited, uint256 amountSyOut ); /// @dev Emitted when any shares are redeemed for base tokens event Redeem( address indexed caller, address indexed receiver, address indexed tokenOut, uint256 amountSyToRedeem, uint256 amountTokenOut ); /// @dev check `assetInfo()` for more information enum AssetType { TOKEN, LIQUIDITY } /// @dev Emitted when (`user`) claims their rewards event ClaimRewards(address indexed user, address[] rewardTokens, uint256[] rewardAmounts); /** * @notice mints an amount of shares by depositing a base token. * @param receiver shares recipient address * @param tokenIn address of the base tokens to mint shares * @param amountTokenToDeposit amount of base tokens to be transferred from (`msg.sender`) * @param minSharesOut reverts if amount of shares minted is lower than this * @return amountSharesOut amount of shares minted * @dev Emits a {Deposit} event * * Requirements: * - (`tokenIn`) must be a valid base token. */ function deposit( address receiver, address tokenIn, uint256 amountTokenToDeposit, uint256 minSharesOut ) external payable returns (uint256 amountSharesOut); /** * @notice redeems an amount of base tokens by burning some shares * @param receiver recipient address * @param amountSharesToRedeem amount of shares to be burned * @param tokenOut address of the base token to be redeemed * @param minTokenOut reverts if amount of base token redeemed is lower than this * @param burnFromInternalBalance if true, burns from balance of `address(this)`, otherwise burns from `msg.sender` * @return amountTokenOut amount of base tokens redeemed * @dev Emits a {Redeem} event * * Requirements: * - (`tokenOut`) must be a valid base token. */ function redeem( address receiver, uint256 amountSharesToRedeem, address tokenOut, uint256 minTokenOut, bool burnFromInternalBalance ) external returns (uint256 amountTokenOut); /** * @notice exchangeRate * syBalance / 1e18 must return the asset balance of the account * @notice vice-versa, if a user uses some amount of tokens equivalent to X asset, the amount of sy he can mint must be X * exchangeRate / 1e18 * @dev SYUtils's assetToSy & syToAsset should be used instead of raw multiplication & division */ function exchangeRate() external view returns (uint256 res); /** * @notice claims reward for (`user`) * @param user the user receiving their rewards * @return rewardAmounts an array of reward amounts in the same order as `getRewardTokens` * @dev * Emits a `ClaimRewards` event * See {getRewardTokens} for list of reward tokens */ function claimRewards(address user) external returns (uint256[] memory rewardAmounts); /** * @notice get the amount of unclaimed rewards for (`user`) * @param user the user to check for * @return rewardAmounts an array of reward amounts in the same order as `getRewardTokens` */ function accruedRewards(address user) external view returns (uint256[] memory rewardAmounts); function rewardIndexesCurrent() external returns (uint256[] memory indexes); function rewardIndexesStored() external view returns (uint256[] memory indexes); /** * @notice returns the list of reward token addresses */ function getRewardTokens() external view returns (address[] memory); /** * @notice returns the address of the underlying yield token */ function yieldToken() external view returns (address); /** * @notice returns all tokens that can mint this SY */ function getTokensIn() external view returns (address[] memory res); /** * @notice returns all tokens that can be redeemed by this SY */ function getTokensOut() external view returns (address[] memory res); function isValidTokenIn(address token) external view returns (bool); function isValidTokenOut(address token) external view returns (bool); function previewDeposit( address tokenIn, uint256 amountTokenToDeposit ) external view returns (uint256 amountSharesOut); function previewRedeem( address tokenOut, uint256 amountSharesToRedeem ) external view returns (uint256 amountTokenOut); /** * @notice This function contains information to interpret what the asset is * @return assetType the type of the asset (0 for ERC20 tokens, 1 for AMM liquidity tokens, 2 for bridged yield bearing tokens like wstETH, rETH on Arbi whose the underlying asset doesn't exist on the chain) * @return assetAddress the address of the asset * @return assetDecimals the decimals of the asset */ function assetInfo() external view returns (AssetType assetType, address assetAddress, uint8 assetDecimals); }
// SPDX-License-Identifier: GPL-3.0-or-later /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IWETH is IERC20 { event Deposit(address indexed dst, uint256 wad); event Withdrawal(address indexed src, uint256 wad); function deposit() external payable; function withdraw(uint256 wad) external; }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "../../interfaces/IPYieldToken.sol"; import "../../interfaces/IPPrincipalToken.sol"; import "../../interfaces/IStandardizedYield.sol"; abstract contract CallbackHelper { enum ActionType { SwapExactSyForYt, SwapYtForSy, SwapExactYtForPt, SwapExactPtForYt } /// ------------------------------------------------------------ /// SwapExactSyForYt /// ------------------------------------------------------------ function _encodeSwapExactSyForYt(address receiver, IPYieldToken YT) internal pure returns (bytes memory res) { res = new bytes(96); uint256 actionType = uint256(ActionType.SwapExactSyForYt); assembly { mstore(add(res, 32), actionType) mstore(add(res, 64), receiver) mstore(add(res, 96), YT) } } function _decodeSwapExactSyForYt(bytes calldata data) internal pure returns (address receiver, IPYieldToken YT) { assembly { // first 32 bytes is ActionType receiver := calldataload(add(data.offset, 32)) YT := calldataload(add(data.offset, 64)) } } /// ------------------------------------------------------------ /// SwapYtForSy (common encode & decode) /// ------------------------------------------------------------ function _encodeSwapYtForSy(address receiver, IPYieldToken YT) internal pure returns (bytes memory res) { res = new bytes(96); uint256 actionType = uint256(ActionType.SwapYtForSy); assembly { mstore(add(res, 32), actionType) mstore(add(res, 64), receiver) mstore(add(res, 96), YT) } } function _decodeSwapYtForSy(bytes calldata data) internal pure returns (address receiver, IPYieldToken YT) { assembly { // first 32 bytes is ActionType receiver := calldataload(add(data.offset, 32)) YT := calldataload(add(data.offset, 64)) } } function _encodeSwapExactYtForPt( address receiver, uint256 netPtOut, IPPrincipalToken PT, IPYieldToken YT ) internal pure returns (bytes memory res) { res = new bytes(160); uint256 actionType = uint256(ActionType.SwapExactYtForPt); assembly { mstore(add(res, 32), actionType) mstore(add(res, 64), receiver) mstore(add(res, 96), netPtOut) mstore(add(res, 128), PT) mstore(add(res, 160), YT) } } function _decodeSwapExactYtForPt( bytes calldata data ) internal pure returns (address receiver, uint256 netPtOut, IPPrincipalToken PT, IPYieldToken YT) { assembly { // first 32 bytes is ActionType receiver := calldataload(add(data.offset, 32)) netPtOut := calldataload(add(data.offset, 64)) PT := calldataload(add(data.offset, 96)) YT := calldataload(add(data.offset, 128)) } } function _encodeSwapExactPtForYt( address receiver, uint256 exactPtIn, uint256 minYtOut, IPYieldToken YT ) internal pure returns (bytes memory res) { res = new bytes(160); uint256 actionType = uint256(ActionType.SwapExactPtForYt); assembly { mstore(add(res, 32), actionType) mstore(add(res, 64), receiver) mstore(add(res, 96), exactPtIn) mstore(add(res, 128), minYtOut) mstore(add(res, 160), YT) } } function _decodeSwapExactPtForYt( bytes calldata data ) internal pure returns (address receiver, uint256 exactPtIn, uint256 minYtOut, IPYieldToken YT) { assembly { // first 32 bytes is ActionType receiver := calldataload(add(data.offset, 32)) exactPtIn := calldataload(add(data.offset, 64)) minYtOut := calldataload(add(data.offset, 96)) YT := calldataload(add(data.offset, 128)) } } /// ------------------------------------------------------------ /// Misc functions /// ------------------------------------------------------------ function _getActionType(bytes calldata data) internal pure returns (ActionType actionType) { assembly { actionType := calldataload(data.offset) } } }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "viaIR": true, "evmVersion": "shanghai", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"actualMaking","type":"uint256"},{"internalType":"uint256","name":"actualTaking","type":"uint256"},{"internalType":"uint256","name":"totalFee","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"limitRouterCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"ptToAccount","type":"int256"},{"internalType":"int256","name":"syToAccount","type":"int256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60808060405234610016576118a6908161001b8239f35b5f80fdfe604060808152600480361015610013575f80fd5b5f3560e01c8063eb3a7d471461086b5763fa483e7214610031575f80fd5b346101ef577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc6060813601126101ef5760449081359083359067ffffffffffffffff602480358286116101ef57366023870112156101ef57858801358381116101ef5782870190833691890101116101ef5780356100ae81610a5b565b806102055750505050505061013f6064926100ca60209361176d565b945f73ffffffffffffffffffffffffffffffffffffffff89519687809681957fdb74aa15000000000000000000000000000000000000000000000000000000008352870135338d840190602090939293604083019473ffffffffffffffffffffffffffffffffffffffff809216845216910152565b03940135165af19081156101fb575f916101c5575b501061015c57005b6101c191519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601f60208201527f536c6970706167653a20494e53554646494349454e545f50545f52455041590060408201520190565b0390fd5b90506020813d6020116101f3575b816101e060209383610984565b810103126101ef57515f610154565b5f80fd5b3d91506101d3565b84513d5f823e3d90fd5b610217819b9994969b97939597610a5b565b6001810361054c5750506064860135926102308461166a565b90805f039a8115918c057fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14821715610521575f8c126101ef57899384516102778161091f565b6002815260209d8e9485830196883689378851966102948861091f565b60028852870198368a378083029283041417156104f657670de0b6b3a764000090818101908181116104ca57670de0b6b3a763ffff0190811161049e57046102db8561170b565b52336102e68261170b565b525f82126101ef579b99918d9261031e8e61030f87956103088c9b9a9961170b565b5190610abe565b61031886611745565b52611745565b9073ffffffffffffffffffffffffffffffffffffffff97889101351690528b519c8d977fb0d889810000000000000000000000000000000000000000000000000000000089528801908d8d8a0152518091526064880194905f5b81811061047757505050868403018887015251918281520191905f5b8c82821061046057505050505f8094928480930393165af180156101fb576103b9575b005b3d805f873e6103c88187610984565b85019486818703126101ef578051908382116101ef57019285601f850112156101ef5783519283116104365750508481819260051b94519061040c83870183610984565b815201928201019283116101ef578301905b82821061042757005b8151815290830190830161041e565b6041907f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b835185528c96509384019390920191600101610394565b929488995080919496839899600194511681520196019101908d97969594928f9492610378565b508960118f7f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b8f60118d917f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b8960118f7f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b8660118c7f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b9295509296985096945061055f81610a5b565b600281036106bc57509561058c610597959697906020820135916040810135916080606083013592013590565b99929790919861176d565b915f81126101ef575f916105d36105b08b602094610abe565b9173ffffffffffffffffffffffffffffffffffffffff8091169c1691828d6111a7565b858551809481937fbcb7ea5d000000000000000000000000000000000000000000000000000000008352338c8401525af19081156106b2575f91610680575b501061062557505050506103b7926111a7565b91601f7f536c6970706167653a20494e53554646494349454e545f53595f5245504159009260206064969551957f08c379a0000000000000000000000000000000000000000000000000000000008752860152840152820152fd5b90506020813d6020116106aa575b8161069b60209383610984565b810103126101ef57515f610612565b3d915061068e565b83513d5f823e3d90fd5b6003919294969395506106ce81610a5b565b03610840579261077a92610707926106fc602096906020820135916040810135916080606083013592013590565b98929196909361176d565b97895f73ffffffffffffffffffffffffffffffffffffffff8d51809b819682957fdb74aa150000000000000000000000000000000000000000000000000000000084523390840190602090939293604083019473ffffffffffffffffffffffffffffffffffffffff809216845216910152565b0393165af1948515610836575f95610802575b5084106107a7575050906107a0916116fe565b1061015c57005b7f536c6970706167653a20494e53554646494349454e545f59545f4f5554000000606492601d889360208b51957f08c379a0000000000000000000000000000000000000000000000000000000008752860152840152820152fd5b9094506020813d60201161082e575b8161081e60209383610984565b810103126101ef5751935f61078d565b3d9150610811565b88513d5f823e3d90fd5b826001867f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b5090346101ef5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101ef5760643567ffffffffffffffff81116101ef57366023820112156101ef5780830135926108c7846109c5565b906108d484519283610984565b84825236602486850101116101ef575f60208661091b97602461090897018387013784010152604435906024359035610af8565b90519182916020835260208301906109ff565b0390f35b6060810190811067ffffffffffffffff82111761093b57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6080810190811067ffffffffffffffff82111761093b57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761093b57604052565b67ffffffffffffffff811161093b57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b91908251928382525f5b848110610a475750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f845f6020809697860101520116010190565b602081830181015184830182015201610a09565b60041115610a6557565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b908160209103126101ef575173ffffffffffffffffffffffffffffffffffffffff811681036101ef5790565b91908203918211610acb57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b918215908161116f575b81611166575b5061114757825192608081602095810103126101ef578381015192600490818510156101ef57604094858401519073ffffffffffffffffffffffffffffffffffffffff92838316968784036101ef57608060608801519701519485168095036101ef57610b7483610a5b565b821593848015611134575b15610ef257610b8d9061166a565b90670de0b6b3a764000090818102918183041490151715610ec65781610bb2916116fe565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908111610ec6578115610e9a5790610bee929104610abe565b948511610e3e5786517fafd27bf5000000000000000000000000000000000000000000000000000000008152888186818a5afa9081156108365791610c438789610c48948d9897965f91610e21575b506111a7565b610a5b565b15610d7c5785517fdb74aa150000000000000000000000000000000000000000000000000000000081523084820190815273ffffffffffffffffffffffffffffffffffffffff909216602083015291908290819060400103815f885af1908115610d72579086915f91610d43575b50938551928380927fd94073d40000000000000000000000000000000000000000000000000000000082525afa9081156101fb5790610cfe915f91610d16575b5033906113a6565b825193840152818301528152610d138161091f565b90565b610d369150863d8811610d3c575b610d2e8183610984565b810190610a92565b5f610cf6565b503d610d24565b82819392503d8311610d6b575b610d5a8183610984565b810103126101ef578590515f610cb6565b503d610d50565b85513d5f823e3d90fd5b85517fdb74aa1500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116928101928352306020840152918290819060400103815f875af180156101fb575f90610df2575b610ded91509233906113a6565b610cfe565b508481813d8311610e1a575b610e088183610984565b810103126101ef57610ded9051610de0565b503d610dfe565b610e389150893d8b11610d3c57610d2e8183610984565b5f610c3d565b606484898951917f08c379a0000000000000000000000000000000000000000000000000000000008352820152601f60248201527f536c6970706167653a20494e53554646494349454e545f53595f4c494d4954006044820152fd5b6012877f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b6011877f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b5092509485949394116110d85780610f0b600192610a5b565b0361107657610f1b8486806111a7565b85517fbcb7ea5d000000000000000000000000000000000000000000000000000000008152308382015287816024815f8a5af190811561106c575f9161103f575b50808211610fe4578791610f6f91610abe565b948651928380927fafd27bf50000000000000000000000000000000000000000000000000000000082525afa908115610d72579084610cfe93925f92610fc3575b508192610fbc926111a7565b33906113a6565b610fbc9250610fde90893d8b11610d3c57610d2e8183610984565b91610fb0565b60648389808a51927f08c379a000000000000000000000000000000000000000000000000000000000845283015260248201527f536c6970706167653a20494e53554646494349454e545f50595f52454445454d6044820152fd5b90508781813d8311611065575b6110568183610984565b810103126101ef57515f610f5c565b503d61104c565b87513d5f823e3d90fd5b85517fd94073d400000000000000000000000000000000000000000000000000000000815287818481895afa90811561106c57866110bc9287925f916110c157506111a7565b610f1b565b610e3891508b3d8d11610d3c57610d2e8183610984565b606483898951917f08c379a0000000000000000000000000000000000000000000000000000000008352820152601f60248201527f536c6970706167653a20494e53554646494349454e545f50595f4c494d4954006044820152fd5b5061113e84610a5b565b60028414610b7f565b5050506040515f60208201525f604082015260408152610d138161091f565b9050155f610b08565b82159150610b02565b3d156111a2573d90611189826109c5565b916111976040519384610984565b82523d5f602084013e565b606090565b82156113a15773ffffffffffffffffffffffffffffffffffffffff908116806112425750505f80809381935af16111dc611178565b50156111e457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6574682073656e64206661696c656400000000000000000000000000000000006044820152fd5b60409391935191602094858401947fa9059cbb00000000000000000000000000000000000000000000000000000000865216602484015260448301526044825261128b82610968565b604051916040830183811067ffffffffffffffff82111761093b576040528483527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656483860152516112ec935f91829182855af16112e6611178565b916117a4565b805190828215928315611389575b505050156113055750565b608490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b6113999350820181019101611755565b5f82816112fa565b505050565b9073ffffffffffffffffffffffffffffffffffffffff9081831692831561166457604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff841660248201526020959193918690829060449082905afa80156101fb575f9061162b575b6b7fffffffffffffffffffffff91501061144a575b5050505050565b8251935f80878701927f095ea7b300000000000000000000000000000000000000000000000000000000948585521692836024890152604497828982015288815261149481610968565b519082875af16114a2611178565b816115fb575b501561159f57915f929183809386519089820193845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff888201528781526114f481610968565b51925af1611500611178565b8161156f575b5015611513578080611443565b606492917f5361666520417070726f766500000000000000000000000000000000000000009151927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b80518015925085908315611587575b5050505f611506565b6115979350820181019101611755565b5f848161157e565b6064867f5361666520417070726f76650000000000000000000000000000000000000000878751927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b80518015925088908315611613575b5050505f6114a8565b6116239350820181019101611755565b5f878161160a565b508581813d831161165d575b6116418183610984565b810103126101ef576b7fffffffffffffffffffffff905161142e565b503d611637565b50505050565b602073ffffffffffffffffffffffffffffffffffffffff60045f9360405194859384927f1d52edc4000000000000000000000000000000000000000000000000000000008452165af19081156116f3575f916116c4575090565b90506020813d6020116116eb575b816116df60209383610984565b810103126101ef575190565b3d91506116d2565b6040513d5f823e3d90fd5b91908201809211610acb57565b8051156117185760200190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8051600110156117185760400190565b908160209103126101ef575180151581036101ef5790565b5f8113156117785790565b7f80000000000000000000000000000000000000000000000000000000000000008114610acb575f0390565b9192901561181f57508151156117b8575090565b3b156117c15790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156118325750805190602001fd5b6101c1906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906109ff56fea2646970667358221220f08372ffe29ea0510d93d8e6fbccd4e962481250f3231e6996e90650ddb060a964736f6c63430008180033
Deployed Bytecode
0x604060808152600480361015610013575f80fd5b5f3560e01c8063eb3a7d471461086b5763fa483e7214610031575f80fd5b346101ef577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc6060813601126101ef5760449081359083359067ffffffffffffffff602480358286116101ef57366023870112156101ef57858801358381116101ef5782870190833691890101116101ef5780356100ae81610a5b565b806102055750505050505061013f6064926100ca60209361176d565b945f73ffffffffffffffffffffffffffffffffffffffff89519687809681957fdb74aa15000000000000000000000000000000000000000000000000000000008352870135338d840190602090939293604083019473ffffffffffffffffffffffffffffffffffffffff809216845216910152565b03940135165af19081156101fb575f916101c5575b501061015c57005b6101c191519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601f60208201527f536c6970706167653a20494e53554646494349454e545f50545f52455041590060408201520190565b0390fd5b90506020813d6020116101f3575b816101e060209383610984565b810103126101ef57515f610154565b5f80fd5b3d91506101d3565b84513d5f823e3d90fd5b610217819b9994969b97939597610a5b565b6001810361054c5750506064860135926102308461166a565b90805f039a8115918c057fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14821715610521575f8c126101ef57899384516102778161091f565b6002815260209d8e9485830196883689378851966102948861091f565b60028852870198368a378083029283041417156104f657670de0b6b3a764000090818101908181116104ca57670de0b6b3a763ffff0190811161049e57046102db8561170b565b52336102e68261170b565b525f82126101ef579b99918d9261031e8e61030f87956103088c9b9a9961170b565b5190610abe565b61031886611745565b52611745565b9073ffffffffffffffffffffffffffffffffffffffff97889101351690528b519c8d977fb0d889810000000000000000000000000000000000000000000000000000000089528801908d8d8a0152518091526064880194905f5b81811061047757505050868403018887015251918281520191905f5b8c82821061046057505050505f8094928480930393165af180156101fb576103b9575b005b3d805f873e6103c88187610984565b85019486818703126101ef578051908382116101ef57019285601f850112156101ef5783519283116104365750508481819260051b94519061040c83870183610984565b815201928201019283116101ef578301905b82821061042757005b8151815290830190830161041e565b6041907f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b835185528c96509384019390920191600101610394565b929488995080919496839899600194511681520196019101908d97969594928f9492610378565b508960118f7f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b8f60118d917f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b8960118f7f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b8660118c7f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b9295509296985096945061055f81610a5b565b600281036106bc57509561058c610597959697906020820135916040810135916080606083013592013590565b99929790919861176d565b915f81126101ef575f916105d36105b08b602094610abe565b9173ffffffffffffffffffffffffffffffffffffffff8091169c1691828d6111a7565b858551809481937fbcb7ea5d000000000000000000000000000000000000000000000000000000008352338c8401525af19081156106b2575f91610680575b501061062557505050506103b7926111a7565b91601f7f536c6970706167653a20494e53554646494349454e545f53595f5245504159009260206064969551957f08c379a0000000000000000000000000000000000000000000000000000000008752860152840152820152fd5b90506020813d6020116106aa575b8161069b60209383610984565b810103126101ef57515f610612565b3d915061068e565b83513d5f823e3d90fd5b6003919294969395506106ce81610a5b565b03610840579261077a92610707926106fc602096906020820135916040810135916080606083013592013590565b98929196909361176d565b97895f73ffffffffffffffffffffffffffffffffffffffff8d51809b819682957fdb74aa150000000000000000000000000000000000000000000000000000000084523390840190602090939293604083019473ffffffffffffffffffffffffffffffffffffffff809216845216910152565b0393165af1948515610836575f95610802575b5084106107a7575050906107a0916116fe565b1061015c57005b7f536c6970706167653a20494e53554646494349454e545f59545f4f5554000000606492601d889360208b51957f08c379a0000000000000000000000000000000000000000000000000000000008752860152840152820152fd5b9094506020813d60201161082e575b8161081e60209383610984565b810103126101ef5751935f61078d565b3d9150610811565b88513d5f823e3d90fd5b826001867f4e487b71000000000000000000000000000000000000000000000000000000005f52525ffd5b5090346101ef5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101ef5760643567ffffffffffffffff81116101ef57366023820112156101ef5780830135926108c7846109c5565b906108d484519283610984565b84825236602486850101116101ef575f60208661091b97602461090897018387013784010152604435906024359035610af8565b90519182916020835260208301906109ff565b0390f35b6060810190811067ffffffffffffffff82111761093b57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6080810190811067ffffffffffffffff82111761093b57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761093b57604052565b67ffffffffffffffff811161093b57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b91908251928382525f5b848110610a475750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f845f6020809697860101520116010190565b602081830181015184830182015201610a09565b60041115610a6557565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b908160209103126101ef575173ffffffffffffffffffffffffffffffffffffffff811681036101ef5790565b91908203918211610acb57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b918215908161116f575b81611166575b5061114757825192608081602095810103126101ef578381015192600490818510156101ef57604094858401519073ffffffffffffffffffffffffffffffffffffffff92838316968784036101ef57608060608801519701519485168095036101ef57610b7483610a5b565b821593848015611134575b15610ef257610b8d9061166a565b90670de0b6b3a764000090818102918183041490151715610ec65781610bb2916116fe565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908111610ec6578115610e9a5790610bee929104610abe565b948511610e3e5786517fafd27bf5000000000000000000000000000000000000000000000000000000008152888186818a5afa9081156108365791610c438789610c48948d9897965f91610e21575b506111a7565b610a5b565b15610d7c5785517fdb74aa150000000000000000000000000000000000000000000000000000000081523084820190815273ffffffffffffffffffffffffffffffffffffffff909216602083015291908290819060400103815f885af1908115610d72579086915f91610d43575b50938551928380927fd94073d40000000000000000000000000000000000000000000000000000000082525afa9081156101fb5790610cfe915f91610d16575b5033906113a6565b825193840152818301528152610d138161091f565b90565b610d369150863d8811610d3c575b610d2e8183610984565b810190610a92565b5f610cf6565b503d610d24565b82819392503d8311610d6b575b610d5a8183610984565b810103126101ef578590515f610cb6565b503d610d50565b85513d5f823e3d90fd5b85517fdb74aa1500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116928101928352306020840152918290819060400103815f875af180156101fb575f90610df2575b610ded91509233906113a6565b610cfe565b508481813d8311610e1a575b610e088183610984565b810103126101ef57610ded9051610de0565b503d610dfe565b610e389150893d8b11610d3c57610d2e8183610984565b5f610c3d565b606484898951917f08c379a0000000000000000000000000000000000000000000000000000000008352820152601f60248201527f536c6970706167653a20494e53554646494349454e545f53595f4c494d4954006044820152fd5b6012877f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b6011877f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b5092509485949394116110d85780610f0b600192610a5b565b0361107657610f1b8486806111a7565b85517fbcb7ea5d000000000000000000000000000000000000000000000000000000008152308382015287816024815f8a5af190811561106c575f9161103f575b50808211610fe4578791610f6f91610abe565b948651928380927fafd27bf50000000000000000000000000000000000000000000000000000000082525afa908115610d72579084610cfe93925f92610fc3575b508192610fbc926111a7565b33906113a6565b610fbc9250610fde90893d8b11610d3c57610d2e8183610984565b91610fb0565b60648389808a51927f08c379a000000000000000000000000000000000000000000000000000000000845283015260248201527f536c6970706167653a20494e53554646494349454e545f50595f52454445454d6044820152fd5b90508781813d8311611065575b6110568183610984565b810103126101ef57515f610f5c565b503d61104c565b87513d5f823e3d90fd5b85517fd94073d400000000000000000000000000000000000000000000000000000000815287818481895afa90811561106c57866110bc9287925f916110c157506111a7565b610f1b565b610e3891508b3d8d11610d3c57610d2e8183610984565b606483898951917f08c379a0000000000000000000000000000000000000000000000000000000008352820152601f60248201527f536c6970706167653a20494e53554646494349454e545f50595f4c494d4954006044820152fd5b5061113e84610a5b565b60028414610b7f565b5050506040515f60208201525f604082015260408152610d138161091f565b9050155f610b08565b82159150610b02565b3d156111a2573d90611189826109c5565b916111976040519384610984565b82523d5f602084013e565b606090565b82156113a15773ffffffffffffffffffffffffffffffffffffffff908116806112425750505f80809381935af16111dc611178565b50156111e457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6574682073656e64206661696c656400000000000000000000000000000000006044820152fd5b60409391935191602094858401947fa9059cbb00000000000000000000000000000000000000000000000000000000865216602484015260448301526044825261128b82610968565b604051916040830183811067ffffffffffffffff82111761093b576040528483527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656483860152516112ec935f91829182855af16112e6611178565b916117a4565b805190828215928315611389575b505050156113055750565b608490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b6113999350820181019101611755565b5f82816112fa565b505050565b9073ffffffffffffffffffffffffffffffffffffffff9081831692831561166457604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff841660248201526020959193918690829060449082905afa80156101fb575f9061162b575b6b7fffffffffffffffffffffff91501061144a575b5050505050565b8251935f80878701927f095ea7b300000000000000000000000000000000000000000000000000000000948585521692836024890152604497828982015288815261149481610968565b519082875af16114a2611178565b816115fb575b501561159f57915f929183809386519089820193845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff888201528781526114f481610968565b51925af1611500611178565b8161156f575b5015611513578080611443565b606492917f5361666520417070726f766500000000000000000000000000000000000000009151927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b80518015925085908315611587575b5050505f611506565b6115979350820181019101611755565b5f848161157e565b6064867f5361666520417070726f76650000000000000000000000000000000000000000878751927f08c379a00000000000000000000000000000000000000000000000000000000084526004840152600c6024840152820152fd5b80518015925088908315611613575b5050505f6114a8565b6116239350820181019101611755565b5f878161160a565b508581813d831161165d575b6116418183610984565b810103126101ef576b7fffffffffffffffffffffff905161142e565b503d611637565b50505050565b602073ffffffffffffffffffffffffffffffffffffffff60045f9360405194859384927f1d52edc4000000000000000000000000000000000000000000000000000000008452165af19081156116f3575f916116c4575090565b90506020813d6020116116eb575b816116df60209383610984565b810103126101ef575190565b3d91506116d2565b6040513d5f823e3d90fd5b91908201809211610acb57565b8051156117185760200190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8051600110156117185760400190565b908160209103126101ef575180151581036101ef5790565b5f8113156117785790565b7f80000000000000000000000000000000000000000000000000000000000000008114610acb575f0390565b9192901561181f57508151156117b8575090565b3b156117c15790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156118325750805190602001fd5b6101c1906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906109ff56fea2646970667358221220f08372ffe29ea0510d93d8e6fbccd4e962481250f3231e6996e90650ddb060a964736f6c63430008180033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.