Contract 0x7Fab20B5e7126b74e299E1055A5E9e76e7A820F7

 
 
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x76b2512db85894b4587170d69cba9667e782515d56c2b9cd1b0926369c7e2d8d0x60806040290792262022-06-02 15:43:07373 days 9 hrs agoFurucombo: Deployer IN  Create: RUniSwapV2Like0 MATIC0.024671550006 50.000000013
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RUniSwapV2Like

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 9 : SafeCast.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such 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.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

File 2 of 9 : AssetResolverBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {IAssetRouter} from "./interfaces/IAssetRouter.sol";
import {IAssetOracle} from "./interfaces/IAssetOracle.sol";

/// @title Asset resolver base contract
abstract contract AssetResolverBase {
    using SafeCast for uint256;

    /// @dev Cast asset value is positive.
    /// @return The calculated amount.
    function _castAssetValue(uint256 amount_) internal pure returns (int256) {
        return amount_.toInt256();
    }

    /// @notice Get the asset oracle.
    /// @return The asset oracle address.
    function _getAssetOracle() internal view returns (IAssetOracle) {
        return IAssetRouter(msg.sender).oracle();
    }

    /// @notice Calculate asset value.
    /// @param asset_ The asset address.
    /// @param amount_ The amount of asset.
    /// @param quote_ The address of the quote token.
    function _calcAssetValue(
        address asset_,
        uint256 amount_,
        address quote_
    ) internal view virtual returns (int256) {
        return IAssetRouter(msg.sender).calcAssetValue(asset_, amount_, quote_);
    }
}

File 3 of 9 : IAssetOracle.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IAssetOracle {
    function calcConversionAmount(
        address base_,
        uint256 baseAmount_,
        address quote_
    ) external view returns (uint256);
}

File 4 of 9 : IAssetRegistry.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IAssetRegistry {
    function bannedResolvers(address) external view returns (bool);

    function register(address asset_, address resolver_) external;

    function unregister(address asset_) external;

    function banResolver(address resolver_) external;

    function unbanResolver(address resolver_) external;

    function resolvers(address asset_) external view returns (address);
}

File 5 of 9 : IAssetResolver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IAssetResolver {
    function calcAssetValue(
        address,
        uint256,
        address
    ) external view returns (int256);
}

File 6 of 9 : IAssetRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IAssetRegistry} from "./IAssetRegistry.sol";
import {IAssetOracle} from "./IAssetOracle.sol";

interface IAssetRouter {
    function oracle() external view returns (IAssetOracle);

    function registry() external view returns (IAssetRegistry);

    function setOracle(address oracle_) external;

    function setRegistry(address registry_) external;

    function calcAssetsTotalValue(
        address[] calldata bases_,
        uint256[] calldata amounts_,
        address quote_
    ) external view returns (uint256);

    function calcAssetValue(
        address asset_,
        uint256 amount_,
        address quote_
    ) external view returns (int256);
}

File 7 of 9 : RUniSwapV2Like.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {IUniswapV2Factory} from "../../../interfaces/IUniswapV2Factory.sol";
import {IUniswapV2Pair} from "../../../interfaces/IUniswapV2Pair.sol";
import {IAssetResolver} from "../../interfaces/IAssetResolver.sol";
import {AssetResolverBase} from "../../AssetResolverBase.sol";

/// @title The uniswap v2 like resolver
contract RUniSwapV2Like is IAssetResolver, AssetResolverBase {
    using SafeCast for int256;

    uint256 private constant _BONE = 10**18;

    /// @notice Calculate asset value given the amount.
    /// @param asset_ The asset address.
    /// @param amount_ The base asset amount.
    /// @param quote_ The address of the quote token.
    /// @return The value of asset in quote token.
    function calcAssetValue(
        address asset_,
        uint256 amount_,
        address quote_
    ) external view returns (int256) {
        // use Weighted Geometric Mean
        // formula = 2*(K*P0*P1)^0.5/totalSupply
        // K: reserve0 * reserve1
        // Pi: price of tokeni from oracle
        // totalSupply: total share of the pool(include protocol fee)

        IUniswapV2Pair pair = IUniswapV2Pair(asset_);
        (uint112 reserve0, uint112 reserve1, ) = pair.getReserves();
        uint256 reserve0value = _calcAssetValue(pair.token0(), reserve0, quote_).toUint256();

        uint256 reserve1value = _calcAssetValue(pair.token1(), reserve1, quote_).toUint256();
        uint256 square = __uniswapSqrt(reserve0value * reserve1value);
        uint256 totalSupply = _getTotalSupplyAtWithdrawal(pair, reserve0, reserve1);

        // Use Bone to avoid calculation loss
        uint256 value = (((2 * square * amount_ * _BONE) / totalSupply) / _BONE);
        return _castAssetValue(value);
    }

    /// @notice Returns Uniswap V2 pair total supply at the time of withdrawal.
    /// @param pair_ The asset address.
    /// @param reserve0_ The reserve0 amount of pair.
    /// @param reserve1_ The reserve1 amount of pair.
    /// @return totalSupply The total supply of pair include fee liquidity.
    function _getTotalSupplyAtWithdrawal(
        IUniswapV2Pair pair_,
        uint256 reserve0_,
        uint256 reserve1_
    ) private view returns (uint256 totalSupply) {
        totalSupply = pair_.totalSupply();
        address feeTo = IUniswapV2Factory(pair_.factory()).feeTo();

        if (feeTo != address(0)) {
            uint256 kLast = pair_.kLast();
            if (kLast != 0) {
                uint256 rootK = __uniswapSqrt(reserve0_ * reserve1_);
                uint256 rootKLast = __uniswapSqrt(kLast);
                if (rootK > rootKLast) {
                    uint256 numerator = totalSupply * (rootK - rootKLast);
                    uint256 denominator = (rootK * 5) + rootKLast;
                    uint256 liquidity = numerator / denominator;
                    totalSupply = totalSupply + liquidity;
                }
            }
        }
    }

    /// @dev Uniswap square root function. See:
    /// https://github.com/Uniswap/uniswap-lib/blob/6ddfedd5716ba85b905bf34d7f1f3c659101a1bc/contracts/libraries/Babylonian.sol
    function __uniswapSqrt(uint256 y_) private 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;
        }
        // else z = 0
    }
}

File 8 of 9 : IUniswapV2Factory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint256);

    function feeTo() external view returns (address);

    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);

    function allPairs(uint256) external view returns (address pair);

    function allPairsLength() external view returns (uint256);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;
}

File 9 of 9 : IUniswapV2Pair.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to) external returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"asset_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"address","name":"quote_","type":"address"}],"name":"calcAssetValue","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b506107f7806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063dedcf67514610030575b600080fd5b61004361003e366004610660565b610055565b60405190815260200160405180910390f35b600080849050600080826001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561009c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100c091906106b9565b5091509150600061014461013f856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012f91906106fe565b856001600160701b031689610255565b6102d7565b905060006101c061013f866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561018c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b091906106fe565b856001600160701b03168a610255565b905060006101d66101d18385610738565b610332565b905060006101f787876001600160701b0316876001600160701b03166103a2565b90506000670de0b6b3a764000082818d610212876002610738565b61021c9190610738565b6102269190610738565b6102309190610757565b61023a9190610757565b9050610245816105cd565b9c9b505050505050505050505050565b60405163dedcf67560e01b81526001600160a01b0380851660048301526024820184905282166044820152600090339063dedcf67590606401602060405180830381865afa1580156102ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cf9190610779565b949350505050565b60008082121561032e5760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f73697469766560448201526064015b60405180910390fd5b5090565b60006003821115610393575080600061034c600283610757565b610357906001610792565b90505b8181101561038d579050806002816103728186610757565b61037c9190610792565b6103869190610757565b905061035a565b50919050565b811561039d575060015b919050565b6000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104069190610779565b90506000846001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610448573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046c91906106fe565b6001600160a01b031663017e7e586040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104cd91906106fe565b90506001600160a01b038116156105c5576000856001600160a01b0316637464fc3d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561051e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105429190610779565b905080156105c35760006105596101d18688610738565b9050600061056683610332565b9050808211156105c057600061057c82846107aa565b6105869087610738565b9050600082610596856005610738565b6105a09190610792565b905060006105ae8284610757565b90506105ba8189610792565b97505050505b50505b505b509392505050565b60006105d8826105de565b92915050565b60006001600160ff1b0382111561032e5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b6064820152608401610325565b6001600160a01b038116811461065d57600080fd5b50565b60008060006060848603121561067557600080fd5b833561068081610648565b925060208401359150604084013561069781610648565b809150509250925092565b80516001600160701b038116811461039d57600080fd5b6000806000606084860312156106ce57600080fd5b6106d7846106a2565b92506106e5602085016106a2565b9150604084015163ffffffff8116811461069757600080fd5b60006020828403121561071057600080fd5b815161071b81610648565b9392505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561075257610752610722565b500290565b60008261077457634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561078b57600080fd5b5051919050565b600082198211156107a5576107a5610722565b500190565b6000828210156107bc576107bc610722565b50039056fea264697066735822122062cd4c774f72dbbe96f7095ba67557f0ebe8fa80afe166d56c1913fe75f9911164736f6c634300080a0033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.