Contract Overview
Balance:
0 MATIC
MATIC Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash |
Method
|
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x9d162130b58179680293c4ef18ee815f0fa9b6d53ffcd2d24bb64eda092b00a5 | 0x60806040 | 31243863 | 245 days 4 hrs ago | 0x07883ebd6f178420f24969279bd425ab0b99f10b | IN | Contract Creation | 0 MATIC | 0.021946796598 |
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x2C9e34F2b8bf0D7C74bC30fbBAbc9dCEf9452b31
Contract Name:
ERC20RootVaultHelper
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IOracle { /// @notice Oracle price for tokens as a Q64.96 value. /// @notice Returns pricing information based on the indexes of non-zero bits in safetyIndicesSet. /// @notice It is possible that not all indices will have their respective prices returned. /// @dev The price is token1 / token0 i.e. how many weis of token1 required for 1 wei of token0. /// The safety indexes are: /// /// 1 - unsafe, this is typically a spot price that can be easily manipulated, /// /// 2 - 4 - more or less safe, this is typically a uniV3 oracle, where the safety is defined by the timespan of the average price /// /// 5 - safe - this is typically a chailink oracle /// @param token0 Reference to token0 /// @param token1 Reference to token1 /// @param safetyIndicesSet Bitmask of safety indices that are allowed for the return prices. For set of safety indexes = { 1 }, safetyIndicesSet = 0x2 /// @return pricesX96 Prices that satisfy safetyIndex and tokens /// @return safetyIndices Safety indices for those prices function priceX96( address token0, address token1, uint256 safetyIndicesSet ) external view returns (uint256[] memory pricesX96, uint256[] memory safetyIndices); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../oracles/IOracle.sol"; interface IERC20RootVaultHelper { function getTvlToken0( uint256[] calldata tvls, address[] calldata tokens, IOracle oracle ) external view returns (uint256 tvl0); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "./external/FullMath.sol"; import "./ExceptionsLibrary.sol"; /// @notice CommonLibrary shared utilities library CommonLibrary { uint256 constant DENOMINATOR = 10**9; uint256 constant D18 = 10**18; uint256 constant YEAR = 365 * 24 * 3600; uint256 constant Q128 = 2**128; uint256 constant Q96 = 2**96; uint256 constant Q48 = 2**48; uint256 constant Q160 = 2**160; uint256 constant UNI_FEE_DENOMINATOR = 10**6; /// @notice Sort uint256 using bubble sort. The sorting is done in-place. /// @param arr Array of uint256 function sortUint(uint256[] memory arr) internal pure { uint256 l = arr.length; for (uint256 i = 0; i < l; ++i) { for (uint256 j = i + 1; j < l; ++j) { if (arr[i] > arr[j]) { uint256 temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } } /// @notice Checks if array of addresses is sorted and all adresses are unique /// @param tokens A set of addresses to check /// @return `true` if all addresses are sorted and unique, `false` otherwise function isSortedAndUnique(address[] memory tokens) internal pure returns (bool) { if (tokens.length < 2) { return true; } for (uint256 i = 0; i < tokens.length - 1; ++i) { if (tokens[i] >= tokens[i + 1]) { return false; } } return true; } /// @notice Projects tokenAmounts onto subset or superset of tokens /// @dev /// Requires both sets of tokens to be sorted. When tokens are not sorted, it's undefined behavior. /// If there is a token in tokensToProject that is not part of tokens and corresponding tokenAmountsToProject > 0, reverts. /// Zero token amount is eqiuvalent to missing token function projectTokenAmounts( address[] memory tokens, address[] memory tokensToProject, uint256[] memory tokenAmountsToProject ) internal pure returns (uint256[] memory) { uint256[] memory res = new uint256[](tokens.length); uint256 t = 0; uint256 tp = 0; while ((t < tokens.length) && (tp < tokensToProject.length)) { if (tokens[t] < tokensToProject[tp]) { res[t] = 0; t++; } else if (tokens[t] > tokensToProject[tp]) { if (tokenAmountsToProject[tp] == 0) { tp++; } else { revert("TPS"); } } else { res[t] = tokenAmountsToProject[tp]; t++; tp++; } } while (t < tokens.length) { res[t] = 0; t++; } return res; } /// @notice Calculated sqrt of uint in X96 format /// @param xX96 input number in X96 format /// @return sqrt of xX96 in X96 format function sqrtX96(uint256 xX96) internal pure returns (uint256) { uint256 sqX96 = sqrt(xX96); return sqX96 << 48; } /// @notice Calculated sqrt of uint /// @param x input number /// @return sqrt of x function sqrt(uint256 x) internal pure returns (uint256) { if (x == 0) return 0; uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; uint256 r1 = x / r; return (r < r1 ? r : r1); } /// @notice Recovers signer address from signed message hash /// @param _ethSignedMessageHash signed message /// @param _signature contatenated ECDSA r, s, v (65 bytes) /// @return Recovered address if the signature is valid, address(0) otherwise function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature) internal pure returns (address) { (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature); return ecrecover(_ethSignedMessageHash, v, r, s); } /// @notice Get ECDSA r, s, v from signature /// @param sig signature (65 bytes) /// @return r ECDSA r /// @return s ECDSA s /// @return v ECDSA v function splitSignature(bytes memory sig) internal pure returns ( bytes32 r, bytes32 s, uint8 v ) { require(sig.length == 65, ExceptionsLibrary.INVALID_LENGTH); assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /// @notice Exceptions stores project`s smart-contracts exceptions library ExceptionsLibrary { string constant ADDRESS_ZERO = "AZ"; string constant VALUE_ZERO = "VZ"; string constant EMPTY_LIST = "EMPL"; string constant NOT_FOUND = "NF"; string constant INIT = "INIT"; string constant DUPLICATE = "DUP"; string constant NULL = "NULL"; string constant TIMESTAMP = "TS"; string constant FORBIDDEN = "FRB"; string constant ALLOWLIST = "ALL"; string constant LIMIT_OVERFLOW = "LIMO"; string constant LIMIT_UNDERFLOW = "LIMU"; string constant INVALID_VALUE = "INV"; string constant INVARIANT = "INVA"; string constant INVALID_TARGET = "INVTR"; string constant INVALID_TOKEN = "INVTO"; string constant INVALID_INTERFACE = "INVI"; string constant INVALID_SELECTOR = "INVS"; string constant INVALID_STATE = "INVST"; string constant INVALID_LENGTH = "INVL"; string constant LOCK = "LCKD"; string constant DISABLED = "DIS"; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.9; /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDiv( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { // diff: original lib works under 0.7.6 with overflows enabled unchecked { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then use the Chinese Remainder Theorem to reconstruct // the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2**256 + prod0 uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(a, b, not(0)) prod0 := mul(a, b) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { require(denominator > 0); assembly { result := div(prod0, denominator) } return result; } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0] // Compute remainder using mulmod uint256 remainder; assembly { remainder := mulmod(a, b, denominator) } // Subtract 256 bit number from 512 bit number assembly { prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. // diff: original uint256 twos = -denominator & denominator; uint256 twos = uint256(-int256(denominator)) & denominator; // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } prod0 |= prod1 * twos; // Invert denominator mod 2**256 // Now that denominator is an odd number, it has an inverse // modulo 2**256 such that denominator * inv = 1 mod 2**256. // Compute the inverse by starting with a seed that is correct // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use Newton-Raphson iteration to improve the precision. // Thanks to Hensel's lifting lemma, this also works in modular // arithmetic, doubling the correct bits in each step. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // inverse mod 2**256 // Because the division is now exact we can divide by multiplying // with the modular inverse of denominator. This will give us the // correct result modulo 2**256. Since the precoditions guarantee // that the outcome is less than 2**256, this is the final result. // We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inv; return result; } } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { // diff: original lib works under 0.7.6 with overflows enabled unchecked { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.9; import "../libraries/ExceptionsLibrary.sol"; import "../interfaces/utils/IERC20RootVaultHelper.sol"; import "../libraries/CommonLibrary.sol"; import "../libraries/external/FullMath.sol"; contract ERC20RootVaultHelper is IERC20RootVaultHelper { function getTvlToken0( uint256[] calldata tvls, address[] calldata tokens, IOracle oracle ) external view returns (uint256 tvl0) { tvl0 = tvls[0]; for (uint256 i = 1; i < tvls.length; i++) { (uint256[] memory pricesX96, ) = oracle.priceX96(tokens[0], tokens[i], 0x30); require(pricesX96.length > 0, ExceptionsLibrary.VALUE_ZERO); uint256 priceX96 = 0; for (uint256 j = 0; j < pricesX96.length; j++) { priceX96 += pricesX96[j]; } priceX96 /= pricesX96.length; tvl0 += FullMath.mulDiv(tvls[i], CommonLibrary.Q96, priceX96); } } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256[]","name":"tvls","type":"uint256[]"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"contract IOracle","name":"oracle","type":"address"}],"name":"getTvlToken0","outputs":[{"internalType":"uint256","name":"tvl0","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50610637806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80634bd8911414610030575b600080fd5b61004361003e366004610375565b610055565b60405190815260200160405180910390f35b60008585600081811061006a5761006a6103f9565b9050602002013590506000600190505b85811015610253576000836001600160a01b0316636d80125b878760008181106100a6576100a66103f9565b90506020020160208101906100bb919061040f565b8888868181106100cd576100cd6103f9565b90506020020160208101906100e2919061040f565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526030604482015260640160006040518083038186803b15801561012f57600080fd5b505afa158015610143573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261016b91908101906104dd565b5090506000815111604051806040016040528060028152602001612b2d60f11b815250906101b55760405162461bcd60e51b81526004016101ac9190610541565b60405180910390fd5b506000805b82518110156101fc578281815181106101d5576101d56103f9565b6020026020010151826101e891906105ac565b9150806101f4816105c4565b9150506101ba565b50815161020990826105df565b9050610232898985818110610220576102206103f9565b90506020020135600160601b8361025d565b61023c90856105ac565b93505050808061024b906105c4565b91505061007a565b5095945050505050565b600080806000198587098587029250828110838203039150508060001415610297576000841161028c57600080fd5b50829004905061030a565b8084116102a357600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150505b9392505050565b60008083601f84011261032357600080fd5b50813567ffffffffffffffff81111561033b57600080fd5b6020830191508360208260051b850101111561035657600080fd5b9250929050565b6001600160a01b038116811461037257600080fd5b50565b60008060008060006060868803121561038d57600080fd5b853567ffffffffffffffff808211156103a557600080fd5b6103b189838a01610311565b909750955060208801359150808211156103ca57600080fd5b506103d788828901610311565b90945092505060408601356103eb8161035d565b809150509295509295909350565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561042157600080fd5b813561030a8161035d565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261045357600080fd5b8151602067ffffffffffffffff808311156104705761047061042c565b8260051b604051601f19603f830116810181811084821117156104955761049561042c565b6040529384528581018301938381019250878511156104b357600080fd5b83870191505b848210156104d2578151835291830191908301906104b9565b979650505050505050565b600080604083850312156104f057600080fd5b825167ffffffffffffffff8082111561050857600080fd5b61051486838701610442565b9350602085015191508082111561052a57600080fd5b5061053785828601610442565b9150509250929050565b600060208083528351808285015260005b8181101561056e57858101830151858201604001528201610552565b81811115610580576000604083870101525b50601f01601f1916929092016040019392505050565b634e487b7160e01b600052601160045260246000fd5b600082198211156105bf576105bf610596565b500190565b60006000198214156105d8576105d8610596565b5060010190565b6000826105fc57634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122027b7e6819b0a498a63b2f96254ac41fbbdbaa0e0810a91a6cf6643c5c178d0eb64736f6c63430008090033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.