Contract 0xe3E777529824F0394a4f9e9dC7f6970d38850d0E

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x0558d1b12c6b9c301a2f0e1ee00a137809c660f60c11b7035edd87c09c4fe5460x60806040107513532019-04-16 0:16:081263 days 23 hrs ago0xa2f79147143e9100e1dd65df277ac54825197148 IN  Create: PolynomialInterestSetter0 Ether0.0040449310
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x2c78c5368707f2b1be9d12c948f5754d5df38870b1b52be06e1a24f2a33ca5d8335848962022-09-01 17:25:3629 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x2989bea770b23032ec1c42b2f8847860f19cffc28d6a4951ad7d6e0e94da7803335848722022-09-01 17:23:2829 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xe8498ae9b8dcd35b7ebbc2cbc9a3686ccf3239e4a163a32dedbf14049cfcbd4f335847872022-09-01 17:16:5229 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x74e1c3fcac5f082e04e26017a3fc2c359680449efd840d80fdbcdb869602af6f335847672022-09-01 17:15:2829 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x3eb8b2ebac1653c27e1b8b2c77f5da5a3810847094abf555cc7e54e362b65112335847222022-09-01 17:12:1229 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x14ec91d3da6d9146c0c0a0814adf43ec4d6d041fbd5692887b4dba3c15bf9fa1335847012022-09-01 17:10:2429 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xfef1a7e9a591d74df87e63e195345f3851aa4dbcca29a3f475180ddb173d0851335846642022-09-01 17:07:2029 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x1c42970a8f0179935d986134ad8df4803602b34b715058c67227f69ec9acccf4335846042022-09-01 17:02:3629 days 6 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x7c7a0aea99bc9629e0ebce5870f6d01b9fb02f6928e52bb1f8e7d6f39f209096335555352022-08-31 3:13:4830 days 20 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x7d78aafd782bef6f5a0adca7b697f4c3de8c3d7ea8090253653dcfe2a4f6e176335080672022-08-28 10:14:0033 days 13 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x46472005dd44fbd706e9cab4877b7f79ec573266228559972946330d7fa9f2c3335079852022-08-28 10:05:5233 days 13 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xa753536cd717b23f854eb7f123f7cf2c14c453e0fcf1729f5be43470daffae11334354032022-08-23 23:23:2838 days 21 mins ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x8e35eccfed58d0b76b4c64be80aa8f1b1f6f9be853c4316abd0e90c3a694d9e9334238882022-08-23 5:34:4038 days 18 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x73b56ea365d4ca3daba7b975f4c0887828c9e7345c1b9fb0cb9eb2b15d68d7b5334235112022-08-23 4:57:2038 days 18 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x694cda7a077bc257a0a48ac3313f28ef4917e7c2cbe94a8f70beefa9c512d02a334235062022-08-23 4:56:4838 days 18 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xad22beba839ce144b18ef272bec1e7a9014a91595cf132659827aeae426eb30b334233942022-08-23 4:46:0038 days 18 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xb32614d2e780668e66d51901db19f11de813099844527d1c68315acd7e0a7f5d334228202022-08-23 3:53:0438 days 19 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xc4d38e8ce9a0d8e23c366dde866e1f001f04be1cc9b2c456313ba086fcc96624334228002022-08-23 3:50:4438 days 19 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xd93bd8b4c829c1b35421c09b61db6c8c6e043c3f08303318e269587de4b2df9a334226942022-08-23 3:41:2438 days 20 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x2ac63b55ccd76a2d0af592e330c1375780a264c6ad4a75b29884930178dec62b334107722022-08-22 8:59:0439 days 14 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x408b92ff81cbcb9176ee531b3cc00f8375ec3d40025f7114f9b52a74c566ed28333886172022-08-20 22:17:5241 days 1 hr ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xe1419b436593bad016c9547898ed30da16b0690ad319e62fd94ddbe09f589cb4333545042022-08-18 21:06:4443 days 2 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0xa9b0063ac397e999391b935b9095ff5e7d3bf7f8ea41567c7808d61c4c0cfa82333544872022-08-18 21:05:2443 days 2 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x64f82c2ef4abe594e7f973373dce2728412910fcacdbdeb054616ee5b87c6b38333540392022-08-18 20:26:4843 days 3 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
0x8fe634544f4d3f733382ef1975eeedfe845b122c2020524e3b02e8a837de9172333540132022-08-18 20:24:4043 days 3 hrs ago 0x4ec3570cadaaee08ae384779b0f3a45ef85289de 0xe3e777529824f0394a4f9e9dc7f6970d38850d0e0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PolynomialInterestSetter

Compiler Version
v0.5.7+commit.6da8b019

Optimization Enabled:
Yes with 10000 runs

Other Settings:
byzantium EvmVersion, Apache-2.0 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-02-26
*/

/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity 0.5.7;
pragma experimental ABIEncoderV2;


/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {
    /**
    * @dev Multiplies two unsigned integers, reverts on 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-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
    * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
    */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
    * @dev Adds two unsigned integers, reverts on overflow.
    */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
    * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}


/**
 * @title Decimal
 * @author dYdX
 *
 * Library that defines a fixed-point number with 18 decimal places.
 */
library Decimal {
    using SafeMath for uint256;

    // ============ Constants ============

    uint256 constant BASE = 10**18;

    // ============ Structs ============

    struct D256 {
        uint256 value;
    }

    // ============ Functions ============

    function one()
        internal
        pure
        returns (D256 memory)
    {
        return D256({ value: BASE });
    }

    function onePlus(
        D256 memory d
    )
        internal
        pure
        returns (D256 memory)
    {
        return D256({ value: d.value.add(BASE) });
    }

    function mul(
        uint256 target,
        D256 memory d
    )
        internal
        pure
        returns (uint256)
    {
        return Math.getPartial(target, d.value, BASE);
    }

    function div(
        uint256 target,
        D256 memory d
    )
        internal
        pure
        returns (uint256)
    {
        return Math.getPartial(target, BASE, d.value);
    }
}

/**
 * @title Require
 * @author dYdX
 *
 * Stringifies parameters to pretty-print revert messages. Costs more gas than regular require()
 */
library Require {

    // ============ Constants ============

    uint256 constant ASCII_ZERO = 48; // '0'
    uint256 constant ASCII_RELATIVE_ZERO = 87; // 'a' - 10
    uint256 constant ASCII_LOWER_EX = 120; // 'x'
    bytes2 constant COLON = 0x3a20; // ': '
    bytes2 constant COMMA = 0x2c20; // ', '
    bytes2 constant LPAREN = 0x203c; // ' <'
    byte constant RPAREN = 0x3e; // '>'
    uint256 constant FOUR_BIT_MASK = 0xf;

    // ============ Library Functions ============

    function that(
        bool must,
        bytes32 file,
        bytes32 reason
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason)
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        uint256 payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        uint256 payloadA,
        uint256 payloadB
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA,
        uint256 payloadB
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA,
        uint256 payloadB,
        uint256 payloadC
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        COMMA,
                        stringify(payloadC),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        bytes32 payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        bytes32 payloadA,
        uint256 payloadB,
        uint256 payloadC
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        COMMA,
                        stringify(payloadC),
                        RPAREN
                    )
                )
            );
        }
    }

    // ============ Private Functions ============

    function stringifyTruncated(
        bytes32 input
    )
        private
        pure
        returns (bytes memory)
    {
        // put the input bytes into the result
        bytes memory result = abi.encodePacked(input);

        // determine the length of the input by finding the location of the last non-zero byte
        for (uint256 i = 32; i > 0; ) {
            // reverse-for-loops with unsigned integer
            /* solium-disable-next-line security/no-modify-for-iter-var */
            i--;

            // find the last non-zero byte in order to determine the length
            if (result[i] != 0) {
                uint256 length = i + 1;

                /* solium-disable-next-line security/no-inline-assembly */
                assembly {
                    mstore(result, length) // r.length = length;
                }

                return result;
            }
        }

        // all bytes are zero
        return new bytes(0);
    }

    function stringify(
        uint256 input
    )
        private
        pure
        returns (bytes memory)
    {
        if (input == 0) {
            return "0";
        }

        // get the final string length
        uint256 j = input;
        uint256 length;
        while (j != 0) {
            length++;
            j /= 10;
        }

        // allocate the string
        bytes memory bstr = new bytes(length);

        // populate the string starting with the least-significant character
        j = input;
        for (uint256 i = length; i > 0; ) {
            // reverse-for-loops with unsigned integer
            /* solium-disable-next-line security/no-modify-for-iter-var */
            i--;

            // take last decimal digit
            bstr[i] = byte(uint8(ASCII_ZERO + (j % 10)));

            // remove the last decimal digit
            j /= 10;
        }

        return bstr;
    }

    function stringify(
        address input
    )
        private
        pure
        returns (bytes memory)
    {
        uint256 z = uint256(input);

        // addresses are "0x" followed by 20 bytes of data which take up 2 characters each
        bytes memory result = new bytes(42);

        // populate the result with "0x"
        result[0] = byte(uint8(ASCII_ZERO));
        result[1] = byte(uint8(ASCII_LOWER_EX));

        // for each byte (starting from the lowest byte), populate the result with two characters
        for (uint256 i = 0; i < 20; i++) {
            // each byte takes two characters
            uint256 shift = i * 2;

            // populate the least-significant character
            result[41 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;

            // populate the most-significant character
            result[40 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;
        }

        return result;
    }

    function stringify(
        bytes32 input
    )
        private
        pure
        returns (bytes memory)
    {
        uint256 z = uint256(input);

        // bytes32 are "0x" followed by 32 bytes of data which take up 2 characters each
        bytes memory result = new bytes(66);

        // populate the result with "0x"
        result[0] = byte(uint8(ASCII_ZERO));
        result[1] = byte(uint8(ASCII_LOWER_EX));

        // for each byte (starting from the lowest byte), populate the result with two characters
        for (uint256 i = 0; i < 32; i++) {
            // each byte takes two characters
            uint256 shift = i * 2;

            // populate the least-significant character
            result[65 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;

            // populate the most-significant character
            result[64 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;
        }

        return result;
    }

    function char(
        uint256 input
    )
        private
        pure
        returns (byte)
    {
        // return ASCII digit (0-9)
        if (input < 10) {
            return byte(uint8(input + ASCII_ZERO));
        }

        // return ASCII letter (a-f)
        return byte(uint8(input + ASCII_RELATIVE_ZERO));
    }
}


/**
 * @title Math
 * @author dYdX
 *
 * Library for non-standard Math functions
 */
library Math {
    using SafeMath for uint256;

    // ============ Constants ============

    bytes32 constant FILE = "Math";

    // ============ Library Functions ============

    /*
     * Return target * (numerator / denominator).
     */
    function getPartial(
        uint256 target,
        uint256 numerator,
        uint256 denominator
    )
        internal
        pure
        returns (uint256)
    {
        return target.mul(numerator).div(denominator);
    }

    /*
     * Return target * (numerator / denominator), but rounded up.
     */
    function getPartialRoundUp(
        uint256 target,
        uint256 numerator,
        uint256 denominator
    )
        internal
        pure
        returns (uint256)
    {
        if (target == 0 || numerator == 0) {
            // SafeMath will check for zero denominator
            return SafeMath.div(0, denominator);
        }
        return target.mul(numerator).sub(1).div(denominator).add(1);
    }

    function to128(
        uint256 number
    )
        internal
        pure
        returns (uint128)
    {
        uint128 result = uint128(number);
        Require.that(
            result == number,
            FILE,
            "Unsafe cast to uint128"
        );
        return result;
    }

    function to96(
        uint256 number
    )
        internal
        pure
        returns (uint96)
    {
        uint96 result = uint96(number);
        Require.that(
            result == number,
            FILE,
            "Unsafe cast to uint96"
        );
        return result;
    }

    function to32(
        uint256 number
    )
        internal
        pure
        returns (uint32)
    {
        uint32 result = uint32(number);
        Require.that(
            result == number,
            FILE,
            "Unsafe cast to uint32"
        );
        return result;
    }

    function min(
        uint256 a,
        uint256 b
    )
        internal
        pure
        returns (uint256)
    {
        return a < b ? a : b;
    }

    function max(
        uint256 a,
        uint256 b
    )
        internal
        pure
        returns (uint256)
    {
        return a > b ? a : b;
    }
}

/**
 * @title Time
 * @author dYdX
 *
 * Library for dealing with time, assuming timestamps fit within 32 bits (valid until year 2106)
 */
library Time {

    // ============ Library Functions ============

    function currentTime()
        internal
        view
        returns (uint32)
    {
        return Math.to32(block.timestamp);
    }
}

/**
 * @title Types
 * @author dYdX
 *
 * Library for interacting with the basic structs used in Solo
 */
library Types {
    using Math for uint256;

    // ============ AssetAmount ============

    enum AssetDenomination {
        Wei, // the amount is denominated in wei
        Par  // the amount is denominated in par
    }

    enum AssetReference {
        Delta, // the amount is given as a delta from the current value
        Target // the amount is given as an exact number to end up at
    }

    struct AssetAmount {
        bool sign; // true if positive
        AssetDenomination denomination;
        AssetReference ref;
        uint256 value;
    }

    // ============ Par (Principal Amount) ============

    // Total borrow and supply values for a market
    struct TotalPar {
        uint128 borrow;
        uint128 supply;
    }

    // Individual principal amount for an account
    struct Par {
        bool sign; // true if positive
        uint128 value;
    }

    function zeroPar()
        internal
        pure
        returns (Par memory)
    {
        return Par({
            sign: false,
            value: 0
        });
    }

    function sub(
        Par memory a,
        Par memory b
    )
        internal
        pure
        returns (Par memory)
    {
        return add(a, negative(b));
    }

    function add(
        Par memory a,
        Par memory b
    )
        internal
        pure
        returns (Par memory)
    {
        Par memory result;
        if (a.sign == b.sign) {
            result.sign = a.sign;
            result.value = SafeMath.add(a.value, b.value).to128();
        } else {
            if (a.value >= b.value) {
                result.sign = a.sign;
                result.value = SafeMath.sub(a.value, b.value).to128();
            } else {
                result.sign = b.sign;
                result.value = SafeMath.sub(b.value, a.value).to128();
            }
        }
        return result;
    }

    function equals(
        Par memory a,
        Par memory b
    )
        internal
        pure
        returns (bool)
    {
        if (a.value == b.value) {
            if (a.value == 0) {
                return true;
            }
            return a.sign == b.sign;
        }
        return false;
    }

    function negative(
        Par memory a
    )
        internal
        pure
        returns (Par memory)
    {
        return Par({
            sign: !a.sign,
            value: a.value
        });
    }

    function isNegative(
        Par memory a
    )
        internal
        pure
        returns (bool)
    {
        return !a.sign && a.value > 0;
    }

    function isPositive(
        Par memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.sign && a.value > 0;
    }

    function isZero(
        Par memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.value == 0;
    }

    // ============ Wei (Token Amount) ============

    // Individual token amount for an account
    struct Wei {
        bool sign; // true if positive
        uint256 value;
    }

    function zeroWei()
        internal
        pure
        returns (Wei memory)
    {
        return Wei({
            sign: false,
            value: 0
        });
    }

    function sub(
        Wei memory a,
        Wei memory b
    )
        internal
        pure
        returns (Wei memory)
    {
        return add(a, negative(b));
    }

    function add(
        Wei memory a,
        Wei memory b
    )
        internal
        pure
        returns (Wei memory)
    {
        Wei memory result;
        if (a.sign == b.sign) {
            result.sign = a.sign;
            result.value = SafeMath.add(a.value, b.value);
        } else {
            if (a.value >= b.value) {
                result.sign = a.sign;
                result.value = SafeMath.sub(a.value, b.value);
            } else {
                result.sign = b.sign;
                result.value = SafeMath.sub(b.value, a.value);
            }
        }
        return result;
    }

    function equals(
        Wei memory a,
        Wei memory b
    )
        internal
        pure
        returns (bool)
    {
        if (a.value == b.value) {
            if (a.value == 0) {
                return true;
            }
            return a.sign == b.sign;
        }
        return false;
    }

    function negative(
        Wei memory a
    )
        internal
        pure
        returns (Wei memory)
    {
        return Wei({
            sign: !a.sign,
            value: a.value
        });
    }

    function isNegative(
        Wei memory a
    )
        internal
        pure
        returns (bool)
    {
        return !a.sign && a.value > 0;
    }

    function isPositive(
        Wei memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.sign && a.value > 0;
    }

    function isZero(
        Wei memory a
    )
        internal
        pure
        returns (bool)
    {
        return a.value == 0;
    }
}


/**
 * @title Interest
 * @author dYdX
 *
 * Library for managing the interest rate and interest indexes of Solo
 */
library Interest {
    using Math for uint256;
    using SafeMath for uint256;

    // ============ Constants ============

    bytes32 constant FILE = "Interest";
    uint64 constant BASE = 10**18;

    // ============ Structs ============

    struct Rate {
        uint256 value;
    }

    struct Index {
        uint96 borrow;
        uint96 supply;
        uint32 lastUpdate;
    }

    // ============ Library Functions ============

    /**
     * Get a new market Index based on the old index and market interest rate.
     * Calculate interest for borrowers by using the formula rate * time. Approximates
     * continuously-compounded interest when called frequently, but is much more
     * gas-efficient to calculate. For suppliers, the interest rate is adjusted by the earningsRate,
     * then prorated the across all suppliers.
     *
     * @param  index         The old index for a market
     * @param  rate          The current interest rate of the market
     * @param  totalPar      The total supply and borrow par values of the market
     * @param  earningsRate  The portion of the interest that is forwarded to the suppliers
     * @return               The updated index for a market
     */
    function calculateNewIndex(
        Index memory index,
        Rate memory rate,
        Types.TotalPar memory totalPar,
        Decimal.D256 memory earningsRate
    )
        internal
        view
        returns (Index memory)
    {
        (
            Types.Wei memory supplyWei,
            Types.Wei memory borrowWei
        ) = totalParToWei(totalPar, index);

        // get interest increase for borrowers
        uint32 currentTime = Time.currentTime();
        uint256 borrowInterest = rate.value.mul(uint256(currentTime).sub(index.lastUpdate));

        // get interest increase for suppliers
        uint256 supplyInterest;
        if (Types.isZero(supplyWei)) {
            supplyInterest = 0;
        } else {
            supplyInterest = Decimal.mul(borrowInterest, earningsRate);
            if (borrowWei.value < supplyWei.value) {
                supplyInterest = Math.getPartial(supplyInterest, borrowWei.value, supplyWei.value);
            }
        }
        assert(supplyInterest <= borrowInterest);

        return Index({
            borrow: Math.getPartial(index.borrow, borrowInterest, BASE).add(index.borrow).to96(),
            supply: Math.getPartial(index.supply, supplyInterest, BASE).add(index.supply).to96(),
            lastUpdate: currentTime
        });
    }

    function newIndex()
        internal
        view
        returns (Index memory)
    {
        return Index({
            borrow: BASE,
            supply: BASE,
            lastUpdate: Time.currentTime()
        });
    }

    /*
     * Convert a principal amount to a token amount given an index.
     */
    function parToWei(
        Types.Par memory input,
        Index memory index
    )
        internal
        pure
        returns (Types.Wei memory)
    {
        uint256 inputValue = uint256(input.value);
        if (input.sign) {
            return Types.Wei({
                sign: true,
                value: inputValue.getPartial(index.supply, BASE)
            });
        } else {
            return Types.Wei({
                sign: false,
                value: inputValue.getPartialRoundUp(index.borrow, BASE)
            });
        }
    }

    /*
     * Convert a token amount to a principal amount given an index.
     */
    function weiToPar(
        Types.Wei memory input,
        Index memory index
    )
        internal
        pure
        returns (Types.Par memory)
    {
        if (input.sign) {
            return Types.Par({
                sign: true,
                value: input.value.getPartial(BASE, index.supply).to128()
            });
        } else {
            return Types.Par({
                sign: false,
                value: input.value.getPartialRoundUp(BASE, index.borrow).to128()
            });
        }
    }

    /*
     * Convert the total supply and borrow principal amounts of a market to total supply and borrow
     * token amounts.
     */
    function totalParToWei(
        Types.TotalPar memory totalPar,
        Index memory index
    )
        internal
        pure
        returns (Types.Wei memory, Types.Wei memory)
    {
        Types.Par memory supplyPar = Types.Par({
            sign: true,
            value: totalPar.supply
        });
        Types.Par memory borrowPar = Types.Par({
            sign: false,
            value: totalPar.borrow
        });
        Types.Wei memory supplyWei = parToWei(supplyPar, index);
        Types.Wei memory borrowWei = parToWei(borrowPar, index);
        return (supplyWei, borrowWei);
    }
}


/**
 * @title IInterestSetter
 * @author dYdX
 *
 * Interface that Interest Setters for Solo must implement in order to report interest rates.
 */
interface IInterestSetter {

    // ============ Public Functions ============

    /**
     * Get the interest rate of a token given some borrowed and supplied amounts
     *
     * @param  token        The address of the ERC20 token for the market
     * @param  borrowWei    The total borrowed token amount for the market
     * @param  supplyWei    The total supplied token amount for the market
     * @return              The interest rate per second
     */
    function getInterestRate(
        address token,
        uint256 borrowWei,
        uint256 supplyWei
    )
        external
        view
        returns (Interest.Rate memory);
}


/**
 * @title PolynomialInterestSetter
 * @author dYdX
 *
 * Interest setter that sets interest based on a polynomial of the usage percentage of the market.
 */
contract PolynomialInterestSetter is
    IInterestSetter
{
    using Math for uint256;
    using SafeMath for uint256;

    // ============ Constants ============

    uint256 constant PERCENT = 100;

    uint256 constant BASE = 10 ** 18;

    uint256 constant SECONDS_IN_A_YEAR = 60 * 60 * 24 * 365;

    uint256 constant BYTE = 8;

    // ============ Structs ============

    struct PolyStorage {
        uint128 maxAPR;
        uint128 coefficients;
    }

    // ============ Storage ============

    PolyStorage g_storage;

    // ============ Constructor ============

    constructor(
        PolyStorage memory params
    )
        public
    {
        // verify that all coefficients add up to 100%
        uint256 sumOfCoefficients = 0;
        for (
            uint256 coefficients = params.coefficients;
            coefficients != 0;
            coefficients >>= BYTE
        ) {
            sumOfCoefficients += coefficients % 256;
        }
        require(
            sumOfCoefficients == PERCENT,
            "Coefficients must sum to 100"
        );

        // store the params
        g_storage = params;
    }

    // ============ Public Functions ============

    /**
     * Get the interest rate given some borrowed and supplied amounts. The interest function is a
     * polynomial function of the utilization (borrowWei / supplyWei) of the market.
     *
     *   - If borrowWei > supplyWei then the utilization is considered to be equal to 1.
     *   - If both are zero, then the utilization is considered to be equal to 0.
     *
     * @return The interest rate per second (times 10 ** 18)
     */
    function getInterestRate(
        address /* token */,
        uint256 borrowWei,
        uint256 supplyWei
    )
        external
        view
        returns (Interest.Rate memory)
    {
        if (borrowWei == 0) {
            return Interest.Rate({
                value: 0
            });
        }

        PolyStorage memory s = g_storage;
        uint256 maxAPR = s.maxAPR;

        if (borrowWei >= supplyWei) {
            return Interest.Rate({
                value: maxAPR / SECONDS_IN_A_YEAR
            });
        }

        uint256 result = 0;
        uint256 polynomial = BASE;

        // for each non-zero coefficient...
        uint256 coefficients = s.coefficients;
        while (true) {
            // gets the lowest-order byte
            uint256 coefficient = coefficients % 256;

            // if non-zero, add to result
            if (coefficient != 0) {
                // no safeAdd since there are at most 16 coefficients
                // no safeMul since (coefficient < 256 && polynomial <= 10**18)
                result += coefficient * polynomial;

                // break if this is the last non-zero coefficient
                if (coefficient == coefficients) {
                    break;
                }
            }

            // increase the order of the polynomial term
            // no safeDiv since supplyWei must be stricly larger than borrowWei
            polynomial = polynomial.mul(borrowWei) / supplyWei;

            // move to next coefficient
            coefficients >>= BYTE;
        }

        // normalize the result
        // no safeMul since result fits within 72 bits and maxAPR fits within 128 bits
        // no safeDiv since the divisor is a non-zero constant
        return Interest.Rate({
            value: result * maxAPR / (SECONDS_IN_A_YEAR * BASE * PERCENT)
        });
    }

    /**
     * Get the maximum APR that this interestSetter will return. The actual APY may be higher
     * depending on how often the interest is compounded.
     *
     * @return The maximum APR
     */
    function getMaxAPR()
        external
        view
        returns (uint256)
    {
        return g_storage.maxAPR;
    }

    /**
     * Get all of the coefficients of the interest calculation, starting from the coefficient for
     * the first-order utilization variable.
     *
     * @return The coefficients
     */
    function getCoefficients()
        external
        view
        returns (uint256[] memory)
    {
        // allocate new array with maximum of 16 coefficients
        uint256[] memory result = new uint256[](16);

        // add the coefficients to the array
        uint256 numCoefficients = 0;
        for (
            uint256 coefficients = g_storage.coefficients;
            coefficients != 0;
            coefficients >>= BYTE
        ) {
            result[numCoefficients] = coefficients % 256;
            numCoefficients++;
        }

        // modify result.length to match numCoefficients
        /* solium-disable-next-line security/no-inline-assembly */
        assembly {
            mstore(result, numCoefficients)
        }

        return result;
    }
}

Contract ABI

[{"constant":true,"inputs":[],"name":"getMaxAPR","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCoefficients","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"borrowWei","type":"uint256"},{"name":"supplyWei","type":"uint256"}],"name":"getInterestRate","outputs":[{"components":[{"name":"value","type":"uint256"}],"name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"name":"maxAPR","type":"uint128"},{"name":"coefficients","type":"uint128"}],"name":"params","type":"tuple"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]

608060405234801561001057600080fd5b50604051604080610675833981018060405261002f9190810190610142565b60208101516000906001608060020a03165b801561005b57610100810691909101906101009004610041565b506064811461009f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610096906101a1565b60405180910390fd5b508051600080546020909301516001608060020a03908116700100000000000000000000000000000000029281166001608060020a0319909416939093179092161790556101f3565b6000604082840312156100fa57600080fd5b61010460406101b7565b90506000610112848461012f565b82525060206101238484830161012f565b60208301525092915050565b600061013b82516101e7565b9392505050565b60006040828403121561015457600080fd5b600061016084846100e8565b949350505050565b6000610175601c836101de565b7f436f656666696369656e7473206d7573742073756d20746f2031303000000000815260200192915050565b602080825281016101b181610168565b92915050565b60405181810167ffffffffffffffff811182821017156101d657600080fd5b604052919050565b90815260200190565b6001608060020a031690565b610473806102026000396000f3fe608060405234801561001057600080fd5b506004361061005d577c010000000000000000000000000000000000000000000000000000000060003504631e68607a8114610062578063afd4c8d614610080578063e8177dcf14610095575b600080fd5b61006a6100b5565b60405161007791906103f7565b60405180910390f35b6100886100cd565b60405161007791906103d8565b6100a86100a33660046102fc565b61015c565b60405161007791906103e9565b6000546fffffffffffffffffffffffffffffffff1690565b604080516010808252610220820190925260609182919060208201610200803883395050600080549293509170010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690505b801561015457610100810683838151811061013957fe5b60209081029190910101526001909101906101009004610122565b508152905090565b6101646102ba565b8261017e5750604080516020810190915260008152610283565b6101866102cd565b50604080518082019091526000546fffffffffffffffffffffffffffffffff8082168084527001000000000000000000000000000000009092041660208301528385106101f25760405180602001604052806301e1338083816101e557fe5b0481525092505050610283565b6020820151600090670de0b6b3a7640000906fffffffffffffffffffffffffffffffff165b60ff81168015610236578281028401935081811415610236575061025c565b87610247848b63ffffffff61028a16565b8161024e57fe5b049250506101009004610217565b6040805160208101909152806b0a3098c68eb9427db8000000858702049052955050505050505b9392505050565b600082610299575060006102b4565b828202828482816102a657fe5b04146102b157600080fd5b90505b92915050565b6040518060200160405280600081525090565b604080518082019091526000808252602082015290565b6000610283823561041b565b60006102838235610418565b60008060006060848603121561031157600080fd5b600061031d86866102e4565b935050602061032e868287016102f0565b925050604061033f868287016102f0565b9150509250925092565b600061035583836103c9565b505060200190565b60006103688261040b565b610372818561040f565b935061037d83610405565b60005b828110156103a857610393868351610349565b955061039e82610405565b9150600101610380565b5093949350505050565b805160208301906103c384826103c9565b50505050565b6103d281610418565b82525050565b60208082528101610283818461035d565b602081016102b482846103b2565b602081016102b482846103c9565b60200190565b5190565b90815260200190565b90565b600073ffffffffffffffffffffffffffffffffffffffff82166102b456fea265627a7a7230582048af2d9629474f4b37687f3807aba12f4e343da394cb73dfe8dd4198972c368c6c6578706572696d656e74616cf500370000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000005000000a0a00

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000005000000a0a00

-----Decoded View---------------
Arg [0] : params (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [1] : 00000000000000000000000000000000000000000000000000005000000a0a00


Deployed ByteCode Sourcemap

28098:4978:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28098:4978:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31936:127;;;:::i;:::-;;;;;;;;;;;;;;;;32275:798;;;:::i;:::-;;;;;;;;29798:1918;;;;;;;;;:::i;:::-;;;;;;;;31936:127;32007:7;32039:16;;;31936:127;:::o;32275:798::-;32475:17;;;32489:2;32475:17;;;;;;;;;32352:16;;;;32475:17;;;;17:15:-1;;105:10;32475:17:0;88:34:-1;-1:-1;;32551:23:0;32631:22;;32449:43;;-1:-1:-1;32551:23:0;32631:22;;;;;;-1:-1:-1;32589:247:0;32668:17;;32589:247;;32789:3;32774:12;:18;32748:6;32755:15;32748:23;;;;;;;;;;;;;;;;;:44;32807:17;;;;;45:20:-1;25:41;;32589:247:0;;;-1:-1:-1;32998:31:0;;33005:6;-1:-1:-1;32275:798:0;:::o;29798:1918::-;29966:20;;:::i;:::-;30008:14;30004:111;;-1:-1:-1;30046:57:0;;;;;;;;;-1:-1:-1;30046:57:0;;30039:64;;30004:111;30127:20;;:::i;:::-;-1:-1:-1;30127:32:0;;;;;;;;;30150:9;30127:32;;;;;;;;;;;;;;;;;30212:22;;;30208:144;;30258:82;;;;;;;;28391:18;30298:6;:26;;;;;;30258:82;;;30251:89;;;;;;30208:144;30499:14;;;;30364;;28337:8;;30476:37;;30524:878;30617:18;;;30699:16;;30695:411;;30912:10;30898:11;:24;30888:34;;;;31029:12;31014:11;:27;31010:81;;;31066:5;;;31010:81;31302:9;31274:25;:10;31289:9;31274:25;:14;:25;:::i;:::-;:37;;;;;;;-1:-1:-1;;45:20;25:41;;30524:878:0;;;31606:102;;;;;;;;;;31661:34;31642:15;;;:54;31606:102;;31599:109;-1:-1:-1;;;;;;29798:1918:0;;;;;;:::o;896:433::-;954:7;1198:6;1194:47;;-1:-1:-1;1228:1:0;1221:8;;1194:47;1265:5;;;1269:1;1265;:5;:1;1289:5;;;;;:10;1281:19;;;;;;1320:1;-1:-1:-1;896:433:0;;;;;:::o;28098:4978::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;28098:4978:0;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;130:118;;197:46;235:6;222:20;197:46;;255:491;;;;393:2;381:9;372:7;368:23;364:32;361:2;;;409:1;406;399:12;361:2;444:1;461:53;506:7;486:9;461:53;;;451:63;;423:97;551:2;569:53;614:7;605:6;594:9;590:22;569:53;;;559:63;;530:98;659:2;677:53;722:7;713:6;702:9;698:22;677:53;;;667:63;;638:98;355:391;;;;;;754:173;;841:46;883:3;875:6;841:46;;;-1:-1;;916:4;907:14;;834:93;966:621;;1111:54;1159:5;1111:54;;;1178:86;1257:6;1252:3;1178:86;;;1171:93;;1284:56;1334:5;1284:56;;;1361:1;1346:219;1371:6;1368:1;1365:13;1346:219;;;1418:63;1477:3;1468:6;1462:13;1418:63;;;1411:70;;1498:60;1551:6;1498:60;;;1488:70;-1:-1;1393:1;1386:9;1346:219;;;-1:-1;1578:3;;1090:497;-1:-1;;;;1090:497;1646:313;1849:22;;1783:4;1774:14;;;1877:61;1778:3;1849:22;1877:61;;;1803:141;1756:203;;;;1966:110;2039:31;2064:5;2039:31;;;2034:3;2027:44;2021:55;;;2210:361;2378:2;2392:47;;;2363:18;;2453:108;2363:18;2547:6;2453:108;;2578:301;2740:2;2725:18;;2754:115;2729:9;2842:6;2754:115;;2886:213;3004:2;2989:18;;3018:71;2993:9;3062:6;3018:71;;3108:121;3217:4;3205:17;;3186:43;3238:107;3328:12;;3312:33;3484:178;3602:19;;;3651:4;3642:14;;3595:67;3670:79;3739:5;3722:27;3756:105;;3948:42;3937:54;;3825:31;3920:76

Swarm Source

bzzr://48af2d9629474f4b37687f3807aba12f4e343da394cb73dfe8dd4198972c368c
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
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.