ETH Price: $3,383.34 (-1.13%)

Contract

0x04Ce60ed10F6D2CfF3AA015fc7b950D13c113be5
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
IdleTokenHelper

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license
/**
 *Submitted for verification at Etherscan.io on 2020-12-31
*/

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// File: interfaces/Idle/IIdleTokenV3_1.sol

pragma solidity 0.6.12;

interface IIdleTokenV3_1 {
    // view
    /**
     * IdleToken price calculation not considering fees, in underlying
     *
     * @return price : price in underlying token
     */
    function tokenPrice() external view returns (uint256 price);

    // view
    /**
     * Map which saves avg idleToken minting price per user
     * Used in calculating redeem price
     *
     * @return price : price in underlying token
     */
    function userAvgPrices(address user) external view returns (uint256 price);


    // view
    /**
     * Current fee on interest gained
     *
     * @return fee : fee on interest gained
     */
    function fee() external view returns (uint256 fee);

    /**
     * @return underlying : underlying token address
     */
    function token() external view returns (address underlying);

    /**
     * Get APR of every ILendingProtocol
     *
     * @return addresses : array of token addresses
     * @return aprs : array of aprs (ordered in respect to the `addresses` array)
     */
    function getAPRs() external view returns (address[] memory addresses, uint256[] memory aprs);

    // external
    // We should save the amount one has deposited to calc interests

    /**
     * Used to mint IdleTokens, given an underlying amount (eg. DAI).
     * This method triggers a rebalance of the pools if needed
     * NOTE: User should 'approve' _amount of tokens before calling mintIdleToken
     * NOTE 2: this method can be paused
     *
     * @param _amount : amount of underlying token to be lended
     * @param _skipRebalance : flag for skipping rebalance for lower gas price
     * @param _referral : referral address
     * @return mintedTokens : amount of IdleTokens minted
     */
    function mintIdleToken(uint256 _amount, bool _skipRebalance, address _referral) external returns (uint256 mintedTokens);

    /**
     * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn
     * This method triggers a rebalance of the pools if needed
     * NOTE: If the contract is paused or iToken price has decreased one can still redeem but no rebalance happens.
     * NOTE 2: If iToken price has decresed one should not redeem (but can do it) otherwise he would capitalize the loss.
     *         Ideally one should wait until the black swan event is terminated
     *
     * @param _amount : amount of IdleTokens to be burned
     * @return redeemedTokens : amount of underlying tokens redeemed
     */
    function redeemIdleToken(uint256 _amount) external returns (uint256 redeemedTokens);
    /**
     * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn
     * and send interest-bearing tokens (eg. cDAI/iDAI) directly to the user.
     * Underlying (eg. DAI) is not redeemed here.
     *
     * @param _amount : amount of IdleTokens to be burned
     */
    function redeemInterestBearingTokens(uint256 _amount) external;

    /**
     * @return : whether has rebalanced or not
     */
    function rebalance() external returns (bool);
}

// File: contracts/IdleTokenHelper.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.6.12;



contract IdleTokenHelper {
    using SafeMath for uint256;

    uint256 constant public FULL_ALLOC = 100000;

    function getMintingPrice(address idleYieldToken) view external returns (uint256 mintingPrice) {
        return _getMintingPrice(idleYieldToken);
    }

    function _getMintingPrice(address idleYieldToken) view internal returns (uint256 mintingPrice) {
        return IIdleTokenV3_1(idleYieldToken).tokenPrice();
    }

    function getRedeemPrice(address idleYieldToken) view external returns (uint256 redeemPrice) {
        return _getRedeemPrice(idleYieldToken, msg.sender);
    }

    function getRedeemPrice(address idleYieldToken, address user) view external returns (uint256 redeemPrice) {
        return _getRedeemPrice(idleYieldToken, user);
    }

    function _getRedeemPrice(address idleYieldToken, address user) view internal returns (uint256 redeemPrice) {
        /*
         *  As per https://github.com/Idle-Labs/idle-contracts/blob/ad0f18fef670ea6a4030fe600f64ece3d3ac2202/contracts/IdleTokenGovernance.sol#L878-L900
         *
         *  Price on minting is currentPrice
         *  Price on redeem must consider the fee
         *
         *  Below the implementation of the following redeemPrice formula
         *
         *  redeemPrice := underlyingAmount/idleTokenAmount
         *
         *  redeemPrice = currentPrice * (1 - scaledFee * ΔP%)
         *
         *  where:
         *  - scaledFee   := fee/FULL_ALLOC
         *  - ΔP% := 0 when currentPrice < userAvgPrice (no gain) and (currentPrice-userAvgPrice)/currentPrice
         *
         *  n.b: gain := idleTokenAmount * ΔP% * currentPrice
         */

        IIdleTokenV3_1 iyt = IIdleTokenV3_1(idleYieldToken);

        uint256 userAvgPrice = iyt.userAvgPrices(user);
        uint256 currentPrice = iyt.tokenPrice();

        // When no deposits userAvgPrice is 0 equiv currentPrice
        // and in the case of issues
        if (userAvgPrice == 0 || currentPrice < userAvgPrice) {
            redeemPrice = currentPrice;
        } else {
            uint256 fee = iyt.fee();

            redeemPrice = ((currentPrice.mul(FULL_ALLOC))
                .sub(
                    fee.mul(
                         currentPrice.sub(userAvgPrice)
                    )
                )).div(FULL_ALLOC);
        }

        return redeemPrice;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"FULL_ALLOC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"idleYieldToken","type":"address"}],"name":"getMintingPrice","outputs":[{"internalType":"uint256","name":"mintingPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"idleYieldToken","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getRedeemPrice","outputs":[{"internalType":"uint256","name":"redeemPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"idleYieldToken","type":"address"}],"name":"getRedeemPrice","outputs":[{"internalType":"uint256","name":"redeemPrice","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50610570806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806320e8e82614610051578063368d9f06146100915780639f3fbecf146100b7578063dfd5b1c9146100dd575b600080fd5b61007f6004803603604081101561006757600080fd5b506001600160a01b03813581169160200135166100e5565b60408051918252519081900360200190f35b61007f600480360360208110156100a757600080fd5b50356001600160a01b03166100fa565b61007f600480360360208110156100cd57600080fd5b50356001600160a01b0316610106565b61007f610111565b60006100f18383610118565b90505b92915050565b60006100f48233610118565b60006100f4826102d3565b620186a081565b6000808390506000816001600160a01b0316630df94ef2856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561016d57600080fd5b505afa158015610181573d6000803e3d6000fd5b505050506040513d602081101561019757600080fd5b505160408051633ffcdacb60e11b815290519192506000916001600160a01b03851691637ff9b596916004808301926020929190829003018186803b1580156101df57600080fd5b505afa1580156101f3573d6000803e3d6000fd5b505050506040513d602081101561020957600080fd5b5051905081158061021957508181105b15610226578093506102ca565b6000836001600160a01b031663ddca3f436040518163ffffffff1660e01b815260040160206040518083038186803b15801561026157600080fd5b505afa158015610275573d6000803e3d6000fd5b505050506040513d602081101561028b57600080fd5b505190506102c6620186a06102c06102ad6102a68688610340565b8590610382565b6102ba86620186a0610382565b90610340565b906103db565b9450505b50505092915050565b6000816001600160a01b0316637ff9b5966040518163ffffffff1660e01b815260040160206040518083038186803b15801561030e57600080fd5b505afa158015610322573d6000803e3d6000fd5b505050506040513d602081101561033857600080fd5b505192915050565b60006100f183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061041d565b600082610391575060006100f4565b8282028284828161039e57fe5b04146100f15760405162461bcd60e51b815260040180806020018281038252602181526020018061051a6021913960400191505060405180910390fd5b60006100f183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506104b4565b600081848411156104ac5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610471578181015183820152602001610459565b50505050905090810190601f16801561049e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836105035760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610471578181015183820152602001610459565b50600083858161050f57fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212208122d9c588b1f088f96598a61f0341b5264d1fd0ef9fd23e2f42e38edd85b9fa64736f6c634300060c0033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806320e8e82614610051578063368d9f06146100915780639f3fbecf146100b7578063dfd5b1c9146100dd575b600080fd5b61007f6004803603604081101561006757600080fd5b506001600160a01b03813581169160200135166100e5565b60408051918252519081900360200190f35b61007f600480360360208110156100a757600080fd5b50356001600160a01b03166100fa565b61007f600480360360208110156100cd57600080fd5b50356001600160a01b0316610106565b61007f610111565b60006100f18383610118565b90505b92915050565b60006100f48233610118565b60006100f4826102d3565b620186a081565b6000808390506000816001600160a01b0316630df94ef2856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561016d57600080fd5b505afa158015610181573d6000803e3d6000fd5b505050506040513d602081101561019757600080fd5b505160408051633ffcdacb60e11b815290519192506000916001600160a01b03851691637ff9b596916004808301926020929190829003018186803b1580156101df57600080fd5b505afa1580156101f3573d6000803e3d6000fd5b505050506040513d602081101561020957600080fd5b5051905081158061021957508181105b15610226578093506102ca565b6000836001600160a01b031663ddca3f436040518163ffffffff1660e01b815260040160206040518083038186803b15801561026157600080fd5b505afa158015610275573d6000803e3d6000fd5b505050506040513d602081101561028b57600080fd5b505190506102c6620186a06102c06102ad6102a68688610340565b8590610382565b6102ba86620186a0610382565b90610340565b906103db565b9450505b50505092915050565b6000816001600160a01b0316637ff9b5966040518163ffffffff1660e01b815260040160206040518083038186803b15801561030e57600080fd5b505afa158015610322573d6000803e3d6000fd5b505050506040513d602081101561033857600080fd5b505192915050565b60006100f183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061041d565b600082610391575060006100f4565b8282028284828161039e57fe5b04146100f15760405162461bcd60e51b815260040180806020018281038252602181526020018061051a6021913960400191505060405180910390fd5b60006100f183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506104b4565b600081848411156104ac5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610471578181015183820152602001610459565b50505050905090810190601f16801561049e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836105035760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610471578181015183820152602001610459565b50600083858161050f57fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212208122d9c588b1f088f96598a61f0341b5264d1fd0ef9fd23e2f42e38edd85b9fa64736f6c634300060c0033

Deployed Bytecode Sourcemap

8718:2420:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9338:169;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;9338:169:0;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;9169:161;;;;;;;;;;;;;;;;-1:-1:-1;9169:161:0;-1:-1:-1;;;;;9169:161:0;;:::i;8837:152::-;;;;;;;;;;;;;;;;-1:-1:-1;8837:152:0;-1:-1:-1;;;;;8837:152:0;;:::i;8785:43::-;;;:::i;9338:169::-;9423:19;9462:37;9478:14;9494:4;9462:15;:37::i;:::-;9455:44;;9338:169;;;;;:::o;9169:161::-;9240:19;9279:43;9295:14;9311:10;9279:15;:43::i;8837:152::-;8909:20;8949:32;8966:14;8949:16;:32::i;8785:43::-;8822:6;8785:43;:::o;9515:1620::-;9601:19;10426:18;10462:14;10426:51;;10490:20;10513:3;-1:-1:-1;;;;;10513:17:0;;10531:4;10513:23;;;;;;;;;;;;;-1:-1:-1;;;;;10513:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10513:23:0;10570:16;;;-1:-1:-1;;;10570:16:0;;;;10513:23;;-1:-1:-1;10547:20:0;;-1:-1:-1;;;;;10570:14:0;;;;;:16;;;;;10513:23;;10570:16;;;;;;;:14;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10570:16:0;;-1:-1:-1;10707:17:0;;;:48;;;10743:12;10728;:27;10707:48;10703:394;;;10786:12;10772:26;;10703:394;;;10831:11;10845:3;-1:-1:-1;;;;;10845:7:0;;:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10845:9:0;;-1:-1:-1;10885:200:0;8822:6;10886:182;10961:88;10996:30;:12;11013;10996:16;:30::i;:::-;10961:3;;:7;:88::i;:::-;10887:28;:12;8822:6;10887:16;:28::i;:::-;10886:52;;:182::i;:::-;10885:188;;:200::i;:::-;10871:214;;10703:394;;11109:18;;;9515:1620;;;;:::o;8997:164::-;9070:20;9125:14;-1:-1:-1;;;;;9110:41:0;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9110:43:0;;8997:164;-1:-1:-1;;8997:164:0:o;1385:136::-;1443:7;1470:43;1474:1;1477;1470:43;;;;;;;;;;;;;;;;;:3;:43::i;2275:471::-;2333:7;2578:6;2574:47;;-1:-1:-1;2608:1:0;2601:8;;2574:47;2645:5;;;2649:1;2645;:5;:1;2669:5;;;;;:10;2661:56;;;;-1:-1:-1;;;2661:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3222:132;3280:7;3307:39;3311:1;3314;3307:39;;;;;;;;;;;;;;;;;:3;:39::i;1824:192::-;1910:7;1946:12;1938:6;;;;1930:29;;;;-1:-1:-1;;;1930:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1982:5:0;;;1824:192::o;3850:278::-;3936:7;3971:12;3964:5;3956:28;;;;-1:-1:-1;;;3956:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3995:9;4011:1;4007;:5;;;;;;;3850:278;-1:-1:-1;;;;;3850:278:0:o

Swarm Source

ipfs://8122d9c588b1f088f96598a61f0341b5264d1fd0ef9fd23e2f42e38edd85b9fa

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

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.