ETH Price: $1,805.90 (+14.02%)

Contract

0xf7EDB240DbF7BBED7D321776AFe87D1FBcFD0A94
Transaction Hash
Method
Block
From
To
Approve3256686362025-04-12 17:46:4010 days ago1744480000IN
0xf7EDB240...FBcFD0A94
0 ETH0.000001950.01
Approve3215426562025-03-31 18:24:0122 days ago1743445441IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000470.01
Approve2982694152025-01-23 1:06:2890 days ago1737594388IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000750.01
Approve2973633422025-01-20 9:58:5492 days ago1737367134IN
0xf7EDB240...FBcFD0A94
0 ETH0.0000020.021032
Redeem2911767072025-01-02 10:17:10110 days ago1735813030IN
0xf7EDB240...FBcFD0A94
0 ETH0.000004560.01
Approve2911761542025-01-02 10:14:52110 days ago1735812892IN
0xf7EDB240...FBcFD0A94
0 ETH0.00000140.01
Approve2890851862024-12-27 8:17:43116 days ago1735287463IN
0xf7EDB240...FBcFD0A94
0 ETH0.000001440.01
Approve2890851682024-12-27 8:17:38116 days ago1735287458IN
0xf7EDB240...FBcFD0A94
0 ETH0.000001440.01
Approve2890851462024-12-27 8:17:32116 days ago1735287452IN
0xf7EDB240...FBcFD0A94
0 ETH0.000001420.01
Transfer2845239372024-12-14 2:32:41130 days ago1734143561IN
0xf7EDB240...FBcFD0A94
0 ETH0.000002340.01
Approve2821521322024-12-07 3:17:46137 days ago1733541466IN
0xf7EDB240...FBcFD0A94
0 ETH0.000001950.01
Transfer2787249862024-11-27 3:58:31147 days ago1732679911IN
0xf7EDB240...FBcFD0A94
0 ETH0.000002850.01
Transfer2787249782024-11-27 3:58:29147 days ago1732679909IN
0xf7EDB240...FBcFD0A94
0 ETH0.000003070.01
Approve2748321162024-11-15 20:09:44158 days ago1731701384IN
0xf7EDB240...FBcFD0A94
0 ETH0.000002480.01
Approve2666992142024-10-23 4:13:04182 days ago1729656784IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000510.01
Approve2650583372024-10-18 9:41:52186 days ago1729244512IN
0xf7EDB240...FBcFD0A94
0 ETH0.000001630.01
Approve2649460032024-10-18 1:52:12187 days ago1729216332IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000860.01
Approve2647607292024-10-17 12:56:06187 days ago1729169766IN
0xf7EDB240...FBcFD0A94
0 ETH0.000002960.01
Approve2646541642024-10-17 5:29:56188 days ago1729142996IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000740.01
Approve2587947122024-09-30 3:41:58205 days ago1727667718IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000550.01
Approve2587887702024-09-30 3:17:06205 days ago1727666226IN
0xf7EDB240...FBcFD0A94
0 ETH0.00000120.016403
Approve2584216352024-09-29 1:35:57206 days ago1727573757IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000590.01
Approve2581249982024-09-28 4:52:51207 days ago1727499171IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000710.01
Approve2372633372024-07-29 11:23:47267 days ago1722252227IN
0xf7EDB240...FBcFD0A94
0 ETH0.000000340.01
Transfer2357519752024-07-25 2:05:58272 days ago1721873158IN
0xf7EDB240...FBcFD0A94
0 ETH0.000002240.038128
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
2911767072025-01-02 10:17:10110 days ago1735813030
0xf7EDB240...FBcFD0A94
0.00751162 ETH
2911767072025-01-02 10:17:10110 days ago1735813030
0xf7EDB240...FBcFD0A94
0.00751162 ETH
2280260902024-07-02 15:35:07294 days ago1719934507
0xf7EDB240...FBcFD0A94
0.03740258 ETH
2280260902024-07-02 15:35:07294 days ago1719934507
0xf7EDB240...FBcFD0A94
0.03740258 ETH
2015665382024-04-16 9:05:22371 days ago1713258322
0xf7EDB240...FBcFD0A94
1.84735945 ETH
2015665382024-04-16 9:05:22371 days ago1713258322
0xf7EDB240...FBcFD0A94
1.84735945 ETH
1947067022024-03-27 9:41:04391 days ago1711532464
0xf7EDB240...FBcFD0A94
0.06274577 ETH
1947067022024-03-27 9:41:04391 days ago1711532464
0xf7EDB240...FBcFD0A94
0.06274577 ETH
1903585462024-03-14 17:45:22404 days ago1710438322
0xf7EDB240...FBcFD0A94
0.03567859 ETH
1903585462024-03-14 17:45:22404 days ago1710438322
0xf7EDB240...FBcFD0A94
0.03567859 ETH
1895307902024-03-12 6:14:33406 days ago1710224073
0xf7EDB240...FBcFD0A94
0.01165593 ETH
1895307902024-03-12 6:14:33406 days ago1710224073
0xf7EDB240...FBcFD0A94
0.01165593 ETH
1895306422024-03-12 6:13:56406 days ago1710224036
0xf7EDB240...FBcFD0A94
0.0832567 ETH
1895306422024-03-12 6:13:56406 days ago1710224036
0xf7EDB240...FBcFD0A94
0.0832567 ETH
1895275192024-03-12 5:59:51406 days ago1710223191
0xf7EDB240...FBcFD0A94
0.13343957 ETH
1895275192024-03-12 5:59:51406 days ago1710223191
0xf7EDB240...FBcFD0A94
0.13343957 ETH
1895274662024-03-12 5:59:38406 days ago1710223178
0xf7EDB240...FBcFD0A94
0.13343968 ETH
1895274662024-03-12 5:59:38406 days ago1710223178
0xf7EDB240...FBcFD0A94
0.13343968 ETH
1895274182024-03-12 5:59:25406 days ago1710223165
0xf7EDB240...FBcFD0A94
0.13343978 ETH
1895274182024-03-12 5:59:25406 days ago1710223165
0xf7EDB240...FBcFD0A94
0.13343978 ETH
1895273702024-03-12 5:59:10406 days ago1710223150
0xf7EDB240...FBcFD0A94
0.13343989 ETH
1895273702024-03-12 5:59:10406 days ago1710223150
0xf7EDB240...FBcFD0A94
0.13343989 ETH
1895272892024-03-12 5:58:49406 days ago1710223129
0xf7EDB240...FBcFD0A94
0.08339185 ETH
1895272892024-03-12 5:58:49406 days ago1710223129
0xf7EDB240...FBcFD0A94
0.08339185 ETH
1895268202024-03-12 5:56:40406 days ago1710223000
0xf7EDB240...FBcFD0A94
0.06670903 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RiseTokenVault

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Arbiscan.io on 2022-01-28
*/

//                 .                                            .
//      *   .                  .              .        .   *          .
//   .         .                     .       .           .      .        .
//         o                             .                   .
//          .              .                  .           .
//           0     .
//                  .          .                 ,                ,    ,
//  .          \          .                         .
//       .      \   ,
//    .          o     .                 .                   .            .
//      .         \                 ,             .                .
//                #\##\#      .                              .        .
//              #  #O##\###                .                        .
//    .        #*#  #\##\###                       .                     ,
//         .   ##*#  #\##\##               .                     .
//       .      ##*#  #o##\#         .                             ,       .
//           .     *#  #\#     .                    .             .          ,
//                       \          .                         .
// ____^/\___^--____/\____O______________/\/\---/\___________---______________
//    /\^   ^  ^    ^                  ^^ ^  '\ ^          ^       ---
//          --           -            --  -      -         ---  __       ^
//    --  __                      ___--  ^  ^                         --  __
//
// The largest leveraged tokens market protocol.
//
// docs: https://docs.risedle.com
// twitter: @risedle
// github: risedle

// Verified using https://dapp.tools

// hevm: flattened sources of src/RiseTokenVault.sol
// SPDX-License-Identifier: MIT AND GPL-3.0-or-later
pragma solidity >=0.8.9 >=0.8.0 <0.9.0;
pragma experimental ABIEncoderV2;

////// lib/openzeppelin-contracts/contracts/utils/Context.sol

/* pragma solidity ^0.8.0; */

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

////// lib/openzeppelin-contracts/contracts/access/Ownable.sol

/* pragma solidity ^0.8.0; */

/* import "../utils/Context.sol"; */

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

////// lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol

/* pragma solidity ^0.8.0; */

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

////// lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol

/* pragma solidity ^0.8.0; */

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

////// lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol

/* pragma solidity ^0.8.0; */

/* import "../IERC20.sol"; */

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

////// lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol

/* pragma solidity ^0.8.0; */

/* import "./IERC20.sol"; */
/* import "./extensions/IERC20Metadata.sol"; */
/* import "../../utils/Context.sol"; */

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

////// lib/openzeppelin-contracts/contracts/utils/Address.sol

/* pragma solidity ^0.8.0; */

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

////// lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol

/* pragma solidity ^0.8.0; */

/* import "../IERC20.sol"; */
/* import "../../../utils/Address.sol"; */

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

////// src/RisedleVault.sol

// Risedle Vault Contract
// It implements money market for Risedle RISE tokens and DROP tokens.
//
// Copyright (c) 2021 Bayu - All rights reserved
// github: pyk
// email: [email protected]
/* pragma solidity >=0.8.9; */
/* pragma experimental ABIEncoderV2; */

/* import { ERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; */
/* import { IERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; */
/* import { IERC20Metadata } from "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; */
/* import { SafeERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; */
/* import { Ownable } from "lib/openzeppelin-contracts/contracts/access/Ownable.sol"; */
/* import { ReentrancyGuard } from "lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol"; */

/// @title Risedle Vault
contract RisedleVault is ERC20, Ownable, ReentrancyGuard {
    using SafeERC20 for IERC20;
    /// @notice Vault's underlying token address
    address internal underlyingToken;
    /// @notice Optimal utilization rate in ether units
    uint256 internal optimalUtilizationRateInEther = 0.9 ether; // 90% utilization
    /// @notice Interest slope 1 in ether units
    uint256 internal interestSlope1InEther = 0.2 ether; // 20% slope 1
    /// @notice Interest slop 2 in ether units
    uint256 internal interestSlope2InEther = 0.6 ether; // 60% slope 2
    /// @notice Number of seconds in a year (approximation)
    uint256 internal immutable totalSecondsInAYear = 31536000;
    /// @notice Maximum borrow rate per second in ether units
    uint256 internal maxBorrowRatePerSecondInEther = 50735667174; // 0.000000050735667174% Approx 393% APY
    /// @notice Performance fee for the lender
    uint256 internal performanceFeeInEther = 0.1 ether; // 10% performance fee
    /// @notice Timestamp that interest was last accrued at
    uint256 internal lastTimestampInterestAccrued;
    /// @notice The total amount of principal borrowed plus interest accrued
    uint256 public totalOutstandingDebt;
    /// @notice The total amount of pending fees to be collected in the vault
    uint256 public totalPendingFees;
    /// @notice The total debt proportion issued by the vault, the usage is similar to the vault token supply. In order to track the outstanding debt of the RISE/DROP token
    uint256 internal totalDebtProportion;
    /// @notice Max vault's total deposit
    uint256 public maxTotalDeposit;
    /// @notice Fee recipient
    address public FEE_RECIPIENT;

    /// @notice Mapping RISE/DROP token to their debt proportion of totalOutstandingDebt
    /// @dev debt = debtProportion[token] * debtProportionRate
    mapping(address => uint256) internal debtProportion;

    /// @notice Event emitted when the interest succesfully accrued
    event InterestAccrued(uint256 previousTimestamp, uint256 currentTimestamp, uint256 previousVaultTotalOutstandingDebt, uint256 previousVaultTotalPendingFees, uint256 borrowRatePerSecondInEther, uint256 elapsedSeconds, uint256 interestAmount, uint256 totalOutstandingDebt, uint256 totalPendingFees);
    /// @notice Event emitted when lender add supply to the vault
    event SupplyAdded(address indexed account, uint256 amount, uint256 ExchangeRateInEther, uint256 mintedAmount);
    /// @notice Event emitted when lender remove supply from the vault
    event SupplyRemoved(address indexed account, uint256 amount, uint256 ExchangeRateInEther, uint256 redeemedAmount);
    /// @notice Event emitted when vault parameters are updated
    event ParametersUpdated(address indexed updater, uint256 u, uint256 s1, uint256 s2, uint256 mr, uint256 fee);
    /// @notice Event emitted when the collected fees are withdrawn
    event FeeCollected(address collector, uint256 total, address feeRecipient);
    /// @notice Event emitted when the fee recipient is updated
    event FeeRecipientUpdated(address updater, address newFeeRecipient);

    /// @notice Construct new RisedleVault
    constructor(
        string memory name, // The name of the vault's token (e.g. Risedle USDC Vault)
        string memory symbol, // The symbol of the vault's token (e.g rvUSDC)
        address underlying, // The ERC20 address of the vault's underlying token (e.g. address of USDC token)
        address feeRecipient // Fee recipient
    ) ERC20(name, symbol) {
        underlyingToken = underlying; // Set the vault underlying token
        lastTimestampInterestAccrued = block.timestamp; // Set the last timestamp accrued
        totalOutstandingDebt = 0; // Set the initial state
        totalPendingFees = 0;
        FEE_RECIPIENT = feeRecipient;
        maxTotalDeposit = 0;
    }

    /// @notice Vault's token use the same decimals as the underlying
    function decimals() public view virtual override returns (uint8) {
        return IERC20Metadata(underlyingToken).decimals();
    }

    /// @notice getUnderlying returns the underlying token of the vault
    function getUnderlying() external view returns (address underlying) {
        underlying = underlyingToken;
    }

    /// @notice getTotalAvailableCash returns the total amount of vault's underlying token that available to borrow
    function getTotalAvailableCash() public view returns (uint256) {
        uint256 vaultBalance = IERC20(underlyingToken).balanceOf(address(this));
        if (totalPendingFees >= vaultBalance) return 0;
        return vaultBalance - totalPendingFees;
    }

    /// @notice calculateUtilizationRateInEther calculates the utilization rate of the vault.
    function calculateUtilizationRateInEther(uint256 available, uint256 outstandingDebt) internal pure returns (uint256) {
        if (outstandingDebt == 0) return 0; // Utilization rate is 0% when there is no outstandingDebt
        if (available == 0 && outstandingDebt > 0) return 1 ether; // Utilization rate is 100% when there is no cash available
        uint256 rateInEther = (outstandingDebt * 1 ether) / (outstandingDebt + available); // utilization rate = amount outstanding debt / (amount available + amount outstanding debt)
        return rateInEther;
    }

    /// @notice getUtilizationRateInEther for external use
    function getUtilizationRateInEther() public view returns (uint256 utilizationRateInEther) {
        uint256 totalAvailable = getTotalAvailableCash(); // Get total available asset
        utilizationRateInEther = calculateUtilizationRateInEther(totalAvailable, totalOutstandingDebt);
    }

    /// @notice calculateBorrowRatePerSecondInEther calculates the borrow rate per second in ether units
    function calculateBorrowRatePerSecondInEther(uint256 utilizationRateInEther) internal view returns (uint256) {
        // utilizationRateInEther should in range [0, 1e18], Otherwise return max borrow rate
        if (utilizationRateInEther >= 1 ether) return maxBorrowRatePerSecondInEther;

        // Calculate the borrow rate
        // See the formula here: https://observablehq.com/@pyk  /ethrise
        if (utilizationRateInEther <= optimalUtilizationRateInEther) {
            // Borrow rate per year = (utilization rate/optimal utilization rate) * interest slope 1
            // Borrow rate per seconds = Borrow rate per year / seconds in a year
            uint256 rateInEther = (utilizationRateInEther * 1 ether) / optimalUtilizationRateInEther;
            uint256 borrowRatePerYearInEther = (rateInEther * interestSlope1InEther) / 1 ether;
            uint256 borrowRatePerSecondInEther = borrowRatePerYearInEther / totalSecondsInAYear;
            return borrowRatePerSecondInEther;
        } else {
            // Borrow rate per year = interest slope 1 + ((utilization rate - optimal utilization rate)/(1-utilization rate)) * interest slope 2
            // Borrow rate per seconds = Borrow rate per year / seconds in a year
            uint256 aInEther = utilizationRateInEther - optimalUtilizationRateInEther;
            uint256 bInEther = 1 ether - utilizationRateInEther;
            uint256 cInEther = (aInEther * 1 ether) / bInEther;
            uint256 dInEther = (cInEther * interestSlope2InEther) / 1 ether;
            uint256 borrowRatePerYearInEther = interestSlope1InEther + dInEther;
            uint256 borrowRatePerSecondInEther = borrowRatePerYearInEther / totalSecondsInAYear;
            // Cap the borrow rate
            if (borrowRatePerSecondInEther >= maxBorrowRatePerSecondInEther) {
                return maxBorrowRatePerSecondInEther;
            }

            return borrowRatePerSecondInEther;
        }
    }

    /// @notice getBorrowRatePerSecondInEther returns the current borrow rate per seconds
    function getBorrowRatePerSecondInEther() public view returns (uint256 borrowRateInEther) {
        uint256 utilizationRateInEther = getUtilizationRateInEther();
        borrowRateInEther = calculateBorrowRatePerSecondInEther(utilizationRateInEther);
    }

    /// @notice getSupplyRatePerSecondInEther calculates the supply rate per second in ether units
    function getSupplyRatePerSecondInEther() public view returns (uint256 supplyRateInEther) {
        uint256 utilizationRateInEther = getUtilizationRateInEther();
        uint256 borrowRateInEther = calculateBorrowRatePerSecondInEther(utilizationRateInEther);
        uint256 nonFeeInEther = 1 ether - performanceFeeInEther;
        uint256 rateForSupplyInEther = (borrowRateInEther * nonFeeInEther) / 1 ether;
        supplyRateInEther = (utilizationRateInEther * rateForSupplyInEther) / 1 ether;
    }

    /// @notice getInterestAmount calculate amount of interest based on the total outstanding debt and borrow rate per second.
    function getInterestAmount(
        uint256 outstandingDebt, // Total of outstanding debt, in underlying decimals
        uint256 borrowRatePerSecondInEther, // Borrow rates per second in ether units
        uint256 elapsedSeconds // Number of seconds elapsed since last accrued
    ) internal pure returns (uint256) {
        if (outstandingDebt == 0 || borrowRatePerSecondInEther == 0 || elapsedSeconds == 0) return 0;
        uint256 interestAmount = (borrowRatePerSecondInEther * elapsedSeconds * outstandingDebt) / 1 ether; // Calculate the amount of interest
        return interestAmount;
    }

    /// @notice setVaultStates update the totalOutstandingDebt and totalPendingFees
    function setVaultStates(uint256 interestAmount, uint256 currentTimestamp) internal {
        uint256 feeAmount = (performanceFeeInEther * interestAmount) / 1 ether; // Get the fee
        totalOutstandingDebt += interestAmount; // Update the states
        totalPendingFees += feeAmount;
        lastTimestampInterestAccrued = currentTimestamp;
    }

    /// @notice accrueInterest accrues interest to totalOutstandingDebt and totalPendingFees
    function accrueInterest() public {
        uint256 currentTimestamp = block.timestamp; // Get the current timestamp, get last timestamp accrued and set the last time accrued
        uint256 previousTimestamp = lastTimestampInterestAccrued;
        if (currentTimestamp == previousTimestamp) return; // If currentTimestamp and previousTimestamp is similar then return early
        uint256 previousVaultTotalOutstandingDebt = totalOutstandingDebt; // For event logging purpose
        uint256 previousVaultTotalPendingFees = totalPendingFees;
        uint256 borrowRatePerSecondInEther = getBorrowRatePerSecondInEther(); // Get borrow rate per second
        uint256 elapsedSeconds = currentTimestamp - previousTimestamp; // Get time elapsed since last accrued
        uint256 interestAmount = getInterestAmount(totalOutstandingDebt, borrowRatePerSecondInEther, elapsedSeconds); // Get the interest amount
        setVaultStates(interestAmount, currentTimestamp); // Update the vault states based on the interest amount:

        emit InterestAccrued(previousTimestamp, currentTimestamp, previousVaultTotalOutstandingDebt, previousVaultTotalPendingFees, borrowRatePerSecondInEther, elapsedSeconds, interestAmount, totalOutstandingDebt, totalPendingFees);
    }

    /// @notice getExchangeRateInEther get the current exchange rate of vault token in term of Vault's underlying token.
    function getExchangeRateInEther() public view returns (uint256) {
        uint256 totalSupply = totalSupply();
        if (totalSupply == 0) {
            // If there is no supply, exchange rate is 1:1
            return 1 ether;
        } else {
            // Otherwise: exchangeRate = (totalAvailable + totalOutstandingDebt) / totalSupply
            uint256 totalAvailable = getTotalAvailableCash();
            uint256 totalAllUnderlyingAsset = totalAvailable + totalOutstandingDebt;
            uint256 exchangeRateInEther = (totalAllUnderlyingAsset * 1 ether) / totalSupply;
            return exchangeRateInEther;
        }
    }

    /// @notice Lender supplies underlying token into the vault and receives vault tokens in exchange
    function addSupply(uint256 amount) external nonReentrant {
        accrueInterest(); // Accrue interest
        if (maxTotalDeposit != 0) require(getTotalAvailableCash() + totalOutstandingDebt + amount < maxTotalDeposit, "!MCR"); // Max cap reached
        uint256 exchangeRateInEther = getExchangeRateInEther(); // Get the exchange rate
        uint256 mintedAmount = (amount * 1 ether) / exchangeRateInEther; // Calculate how much vault token we need to send to the lender
        IERC20(underlyingToken).safeTransferFrom(msg.sender, address(this), amount); // Transfer asset from lender to the vault
        _mint(msg.sender, mintedAmount); // Send vault token to the lender
        emit SupplyAdded(msg.sender, amount, exchangeRateInEther, mintedAmount);
    }

    /// @notice Lender burn vault tokens and receives underlying tokens in exchange
    function removeSupply(uint256 amount) external nonReentrant {
        accrueInterest(); // Accrue interest
        uint256 exchangeRateInEther = getExchangeRateInEther(); // Get the exchange rate
        uint256 redeemedAmount = (exchangeRateInEther * amount) / 1 ether; // Calculate how much underlying token we need to send to the lender
        IERC20(underlyingToken).safeTransfer(msg.sender, redeemedAmount); // Transfer Vault's underlying token from the vault to the lender
        _burn(msg.sender, amount); // Burn the vault tokens from the lender
        emit SupplyRemoved(msg.sender, amount, exchangeRateInEther, redeemedAmount);
    }

    /// @notice getDebtProportionRateInEther returns the proportion of borrow amount relative to the totalOutstandingDebt
    function getDebtProportionRateInEther() internal view returns (uint256 debtProportionRateInEther) {
        if (totalOutstandingDebt == 0 || totalDebtProportion == 0) {
            return 1 ether;
        }
        debtProportionRateInEther = (totalOutstandingDebt * 1 ether) / totalDebtProportion;
    }

    /// @notice getOutstandingDebt returns the debt owed by the RISE/DROP tokens
    function getOutstandingDebt(address token) public view returns (uint256) {
        // If there is no debt, return 0
        if (totalOutstandingDebt == 0) return 0;
        // Calculate the outstanding debt
        // outstanding debt = debtProportion * debtProportionRate
        uint256 debtProportionRateInEther = getDebtProportionRateInEther();
        uint256 a = (debtProportion[token] * debtProportionRateInEther);
        uint256 b = 1 ether;
        uint256 outstandingDebt = a / b + (a % b == 0 ? 0 : 1); // Rounds up instead of rounding down
        return outstandingDebt;
    }

    /// @notice setBorrowStates sets the debt of the RISE/DROP token
    function setBorrowStates(address token, uint256 borrowAmount) internal {
        uint256 debtProportionRateInEther = getDebtProportionRateInEther();
        totalOutstandingDebt += borrowAmount;
        uint256 borrowProportion = (borrowAmount * 1 ether) / debtProportionRateInEther;
        totalDebtProportion += borrowProportion;
        debtProportion[token] = debtProportion[token] + borrowProportion;
    }

    /// @notice setRepayStates repay the debt of the RISE tokens
    function setRepayStates(address token, uint256 repayAmount) internal {
        uint256 debtProportionRateInEther = getDebtProportionRateInEther();
        // Handle repay amount larger than existing total debt
        if (repayAmount > totalOutstandingDebt) {
            totalOutstandingDebt = 0;
        } else {
            totalOutstandingDebt -= repayAmount;
        }
        uint256 repayProportion = (repayAmount * 1 ether) / debtProportionRateInEther;
        if (repayProportion > totalDebtProportion) {
            totalDebtProportion = 0;
        } else {
            totalDebtProportion -= repayProportion;
        }
        if (repayProportion > debtProportion[token]) {
            debtProportion[token] -= 0;
        } else {
            debtProportion[token] -= repayProportion;
        }
    }

    /// @notice setVaultParameters updates the vault parameters.
    function setVaultParameters(
        uint256 u,
        uint256 s1,
        uint256 s2,
        uint256 mr,
        uint256 fee
    ) external onlyOwner {
        // Update vault parameters
        optimalUtilizationRateInEther = u;
        interestSlope1InEther = s1;
        interestSlope2InEther = s2;
        maxBorrowRatePerSecondInEther = mr;
        performanceFeeInEther = fee;

        emit ParametersUpdated(msg.sender, u, s1, s2, mr, fee);
    }

    /// @notice getVaultParameters returns the current vault parameters.
    function getVaultParameters()
        external
        view
        returns (
            uint256 _optimalUtilizationRateInEther,
            uint256 _interestSlope1InEther,
            uint256 _interestSlope2InEther,
            uint256 _maxBorrowRatePerSecondInEther,
            uint256 _performanceFeeInEther
        )
    {
        _optimalUtilizationRateInEther = optimalUtilizationRateInEther;
        _interestSlope1InEther = interestSlope1InEther;
        _interestSlope2InEther = interestSlope2InEther;
        _maxBorrowRatePerSecondInEther = maxBorrowRatePerSecondInEther;
        _performanceFeeInEther = performanceFeeInEther;
    }

    /// @notice setFeeRecipient sets the fee recipient address.
    function setFeeRecipient(address account) external onlyOwner {
        FEE_RECIPIENT = account;
        emit FeeRecipientUpdated(msg.sender, account);
    }

    /// @notice collectVaultPendingFees withdraws collected fees to the FEE_RECIPIENT address
    function collectVaultPendingFees() external {
        accrueInterest(); // Accrue interest
        uint256 collectedFees = totalPendingFees;
        IERC20(underlyingToken).safeTransfer(FEE_RECIPIENT, collectedFees);
        totalPendingFees = 0;

        emit FeeCollected(msg.sender, collectedFees, FEE_RECIPIENT);
    }

    /// @notice setVaultMaxTotalDeposit sets the max total deposit of the vault
    function setVaultMaxTotalDeposit(uint256 amount) external onlyOwner {
        maxTotalDeposit = amount;
    }
}

////// src/interfaces/IRisedleERC20.sol

/* pragma solidity >=0.8.9; */
/* pragma experimental ABIEncoderV2; */

interface IRisedleERC20 {
    function mint(address to, uint256 amount) external;

    function burn(address from, uint256 amount) external;
}

////// src/interfaces/IRisedleOracle.sol

/* pragma solidity >=0.8.9; */
/* pragma experimental ABIEncoderV2; */

interface IRisedleOracle {
    // Get price of the collateral based on the vault's underlying asset
    // For example ETH that trade 4000 USDC is returned as 4000 * 1e6 because USDC have 6 decimals
    function getPrice() external view returns (uint256 price);
}

////// src/interfaces/IRisedleSwap.sol

/* pragma solidity >=0.8.9; */
/* pragma experimental ABIEncoderV2; */

interface IRisedleSwap {
    /**
     * @notice Swap tokenIn to tokenOut
     * @param tokenIn The ERC20 address of token that we want to swap
     * @param tokenOut The ERC20 address of token that we want swap to
     * @param maxAmountIn The maximum amount of tokenIn to get the tokenOut with amountOut
     * @param amountOut The amount of tokenOut that we want to get
     * @return amountIn The amount of tokenIn that we spend to get the amountOut of tokenOut
     */
    function swap(
        address tokenIn,
        address tokenOut,
        uint256 maxAmountIn,
        uint256 amountOut
    ) external returns (uint256 amountIn);
}

////// src/interfaces/IWETH9.sol
/* pragma solidity >=0.8.9; */
/* pragma experimental ABIEncoderV2; */

/* import { IERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; */

/// @title Interface for WETH9
/// @author bayu (github.com/pyk)
interface IWETH9 is IERC20 {
    /// @notice Deposit ether to get wrapped ether
    function deposit() external payable;

    /// @notice Withdraw wrapped ether to get ether
    function withdraw(uint256) external;
}

////// src/tokens/RisedleERC20.sol

// Risedle ERC20 Contract
// ERC20 contract to leverage and hedge token.
// It allows the owner to mint/burn token. On the production setup,
// only Risedle Vault can mint/burn this token.
// It's been validated using dapp tools HEVM verification.
//
// Copyright (c) 2021 Bayu - All rights reserved
// github: pyk
// email: [email protected]

/* pragma solidity >=0.8.9; */
/* pragma experimental ABIEncoderV2; */

/* import { ERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; */
/* import { Ownable } from "lib/openzeppelin-contracts/contracts/access/Ownable.sol"; */

/// @notice Risedle ERC20 implementation
contract RisedleERC20 is ERC20, Ownable {
    uint8 private _decimals;

    /// @notice Construct new Risedle ERC20 token
    /// @param name The ERC20 token name
    /// @param symbol The ERC20 token symbol
    /// @param owner The ERC20 owner contract
    /// @param decimals_ The ERC20 token decimals
    constructor(
        string memory name,
        string memory symbol,
        address owner,
        uint8 decimals_
    ) ERC20(name, symbol) {
        // Set the owner
        transferOwnership(owner);

        // Set the decimals
        _decimals = decimals_;
    }

    function decimals() public view virtual override returns (uint8) {
        return _decimals;
    }

    /// @notice mint mints new token to the specified address
    /// @dev Used when user deposit asset in the vault or mint new leverage/hedge
    ///      token. Only owner can call this function.
    function mint(address to, uint256 amount) external onlyOwner {
        _mint(to, amount);
    }

    /// @notice burn burns the token from the specified address
    /// @dev Used when user withdraw asset in the vault or redeem  leverage/hedge
    ///      token. Only owner can call this function.
    function burn(address from, uint256 amount) external onlyOwner {
        _burn(from, amount);
    }
}

////// src/RiseTokenVault.sol
// Copyright (c) 2021 Bayu - All rights reserved
/* pragma solidity >=0.8.9; */
/* pragma experimental ABIEncoderV2; */

/* import { IERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; */
/* import { SafeERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; */
/* import { IERC20Metadata } from "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; */
/* import { RisedleVault } from "./RisedleVault.sol"; */
/* import { RisedleERC20 } from "./tokens/RisedleERC20.sol"; */
/* import { IRisedleOracle } from "./interfaces/IRisedleOracle.sol"; */
/* import { IRisedleSwap } from "./interfaces/IRisedleSwap.sol"; */
/* import { IRisedleERC20 } from "./interfaces/IRisedleERC20.sol"; */
/* import { IWETH9 } from "./interfaces/IWETH9.sol"; */

/// @title Rise Token Vault
/// @author bayu (github.com/pyk)
/// @dev It implements leveraged tokens. User can mint leveraged tokens, redeem leveraged tokens and trigger the rebalance. Rebalance only get execute when the criteria is met.
contract RiseTokenVault is RisedleVault {
    using SafeERC20 for IERC20;

    /// @notice RiseTokenMetadata contains the metadata of TOKENRISE
    struct RiseTokenMetadata {
        bool isETH; // True if the collateral is eth
        address token; // Address of ETF token ERC20, make sure this vault can mint & burn this token
        address collateral; // ETF underlying asset (e.g. WETH address)
        address oracleContract; // Contract address that implement IRisedleOracle interface
        address swapContract; // Contract address that implment IRisedleSwap interface
        uint256 maxSwapSlippageInEther; // Maximum swap slippage for mint, redeem and rebalancing (e.g. 1% is 0.01 ether or 0.01 * 1e18)
        uint256 initialPrice; // In term of vault's underlying asset (e.g. 100 USDC -> 100 * 1e6, coz is 6 decimals for USDC)
        uint256 feeInEther; // Creation and redemption fee in ether units (e.g. 0.1% is 0.001 ether)
        uint256 totalCollateralPlusFee; // Total amount of underlying managed by this ETF
        uint256 totalPendingFees; // Total amount of creation and redemption pending fees in ETF underlying
        uint256 minLeverageRatioInEther; // Minimum leverage ratio in ether units (e.g. 2x is 2 ether = 2*1e18)
        uint256 maxLeverageRatioInEther; // Maximum leverage ratio  in ether units (e.g. 3x is 3 ether = 3*1e18)
        uint256 maxRebalancingValue; // The maximum value of buy/sell when rebalancing (e.g. 500K USDC is 500000 * 1e6)
        uint256 rebalancingStepInEther; // The rebalancing step in ether units (e.g. 0.2 is 0.2 ether or 0.2 * 1e18)
        uint256 maxTotalCollateral; // Limit the mint amount
    }

    /// @notice Mapping TOKENRISE to their metadata
    mapping(address => RiseTokenMetadata) riseTokens;

    event RiseTokenCreated(address indexed creator, address token); // Event emitted when new TOKENRISE is created
    event RiseTokenMinted(address indexed user, address indexed riseToken, uint256 mintedAmount); // Event emitted when TOKENRISE is minted
    event RiseTokenRebalanced(address indexed executor, uint256 previousLeverageRatioInEther); // Event emitted when TOKENRISE is successfully rebalanced
    event RiseTokenBurned(address indexed user, address indexed riseToken, uint256 redeemedAmount); // Event emitted when TOKENRISE is burned
    event MaxTotalCollateralUpdated(address indexed token, uint256 newMaxTotalCollateral); // Event emitted when max collateral is set
    event OracleContractUpdated(address indexed token, address indexed oracle); // Event emitted when new oracle contract is set
    event SwapContractUpdated(address indexed token, address indexed swap); // Event emitted when new swap contract is set

    /// @notice Construct new RiseTokenVault
    constructor(
        string memory name, // The name of the vault's token (e.g. Risedle USDC Vault)
        string memory symbol, // The symbol of the vault's token (e.g rvUSDC)
        address underlying, // The ERC20 address of the vault's underlying token (e.g. address of USDC token)
        address feeRecipient // Vault's fee recipient
    ) RisedleVault(name, symbol, underlying, feeRecipient) {}

    /// @notice create creates new TOKENRISE
    function create(
        bool isETH, // True if the collateral is ETH
        address tokenRiseAddress, // ERC20 token address that only RiseTokenVault can mint and burn
        address collateral, // The underlying token of TOKENRISE (e.g. WBTC), it's WETH if the isETH is true
        address oracleContract, // Contract address that implement IRisedleOracle interface
        address swapContract, // Uniswap V3 like token swapper
        uint256 maxSwapSlippageInEther, // Maximum slippage when mint, redeem and rebalancing (1% is 0.01 ether or 0.01*1e18)
        uint256 initialPrice, // Initial price of the TOKENRISE based on the Vault's underlying asset (e.g. 100 USDC => 100 * 1e6)
        uint256 feeInEther, // Creation and redemption fee in ether units (e.g. 0.001 ether = 0.1%)
        uint256 minLeverageRatioInEther, // Minimum leverage ratio in ether units (e.g. 2x is 2 ether = 2*1e18)
        uint256 maxLeverageRatioInEther, // Maximum leverage ratio  in ether units (e.g. 3x is 3 ether = 3*1e18)
        uint256 maxRebalancingValue, // The maximum value of buy/sell when rebalancing (e.g. 500K USDC is 500000 * 1e6)
        uint256 rebalancingStepInEther // The rebalancing step in ether units (e.g. 0.2 is 0.2 ether or 0.2 * 1e18)
    ) external onlyOwner {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[tokenRiseAddress];
        require(riseTokenMetadata.feeInEther == 0, "!AE"); // Make sure token metadata is not exists

        // Create new Rise metadata
        riseTokens[tokenRiseAddress] = RiseTokenMetadata({
            isETH: isETH,
            token: tokenRiseAddress,
            collateral: collateral,
            oracleContract: oracleContract,
            swapContract: swapContract,
            maxSwapSlippageInEther: maxSwapSlippageInEther,
            initialPrice: initialPrice,
            feeInEther: feeInEther,
            minLeverageRatioInEther: minLeverageRatioInEther,
            maxLeverageRatioInEther: maxLeverageRatioInEther,
            maxRebalancingValue: maxRebalancingValue,
            rebalancingStepInEther: rebalancingStepInEther,
            totalCollateralPlusFee: 0,
            totalPendingFees: 0,
            maxTotalCollateral: 0
        });

        // Emit event
        emit RiseTokenCreated(msg.sender, tokenRiseAddress);
    }

    /// @notice getMetadata returns the metadata of the TOKENRISE
    function getMetadata(address token) external view returns (RiseTokenMetadata memory) {
        return riseTokens[token];
    }

    /// @notice calculateCollateralPerRiseToken returns the collateral shares per TOKENRISE
    function calculateCollateralPerRiseToken(
        uint256 riseTokenSupply, // The total supply of the TOKENRISE
        uint256 totalCollateralPlusFee, // The total collateral managed by the TOKENRISE
        uint256 totalPendingFees, // The total pending fees in the TOKENRISE
        uint8 collateralDecimals // The collateral decimals (e.g. ETH is 18 decimals)
    ) internal pure returns (uint256 collateralPerRiseToken) {
        if (riseTokenSupply == 0) return 0;
        collateralPerRiseToken = ((totalCollateralPlusFee - totalPendingFees) * (10**collateralDecimals)) / riseTokenSupply; // Get collateral per TOKENRISE
    }

    /// @notice getCollateralPerRiseToken returns the collateral shares per TOKENRISE
    function getCollateralPerRiseToken(address token) external view returns (uint256 collateralPerRiseToken) {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        if (riseTokenMetadata.feeInEther == 0) return 0; // Make sure the TOKENRISE is exists
        uint256 riseTokenSupply = IERC20(riseTokenMetadata.token).totalSupply();
        uint8 collateralDecimals = IERC20Metadata(riseTokenMetadata.token).decimals();
        collateralPerRiseToken = calculateCollateralPerRiseToken(riseTokenSupply, riseTokenMetadata.totalCollateralPlusFee, riseTokenMetadata.totalPendingFees, collateralDecimals);
    }

    /// @notice calculateDebtPerRiseToken returns the debt shares per TOKENRISE
    function calculateDebtPerRiseToken(
        address token, // The address of TOKENRISE (ERC20)
        uint256 totalSupply, // The current total supply of the TOKENRISE
        uint8 collateralDecimals // The decimals of the collateral token (e.g. ETH have 18 decimals)
    ) internal view returns (uint256 debtPerRiseToken) {
        if (totalSupply == 0) return 0;
        uint256 totalDebt = getOutstandingDebt(token); // Get total TOKENRISE debt
        if (totalDebt == 0) return 0;
        uint256 a = (totalDebt * (10**collateralDecimals));
        uint256 b = totalSupply;
        debtPerRiseToken = a / b + (a % b == 0 ? 0 : 1); // Rounds up instead of rounding down
    }

    /// @notice getDebtPerRiseToken returns the debt shares per TOKENRISE
    function getDebtPerRiseToken(address token) external view returns (uint256 debtPerRiseToken) {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        if (riseTokenMetadata.feeInEther == 0) return 0; // Make sure the TOKENRISE is exists
        uint256 totalSupply = IERC20(riseTokenMetadata.token).totalSupply();
        uint8 collateralDecimals = IERC20Metadata(riseTokenMetadata.token).decimals();
        debtPerRiseToken = calculateDebtPerRiseToken(riseTokenMetadata.token, totalSupply, collateralDecimals);
    }

    /// @notice calculateNAV calculates the net-asset value of the ETF
    function calculateNAV(
        uint256 collateralPerRiseToken, // The amount of collateral per TOKENRISE (e.g 0.5 ETH is 0.5*1e18)
        uint256 debtPerRiseToken, // The amount of debt per TOKENRISE (e.g. 50 USDC is 50*1e6)
        uint256 collateralPrice, // The collateral price in term of supply asset (e.g 100 USDC is 100*1e6)
        uint256 etfInitialPrice, // The initial price of the ETF in terms od supply asset (e.g. 100 USDC is 100*1e6)
        uint8 collateralDecimals // The decimals of the collateral token
    ) internal pure returns (uint256 nav) {
        if (collateralPerRiseToken == 0 || debtPerRiseToken == 0) return etfInitialPrice;
        uint256 collateralValuePerRiseToken = (collateralPerRiseToken * collateralPrice) / (10**collateralDecimals); // Get the collateral value in term of the supply
        nav = collateralValuePerRiseToken - debtPerRiseToken; // Calculate the NAV
    }

    /// @notice Get the net-asset value of the TOKENRISE
    function getNAV(address token) public view returns (uint256 nav) {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        if (riseTokenMetadata.feeInEther == 0) return 0; // Make sure the TOKENRISE is exists
        uint256 collateralPrice = IRisedleOracle(riseTokenMetadata.oracleContract).getPrice(); // For example WETH/USDC would trading around 4000 USDC (4000 * 1e6)
        uint256 totalSupply = IERC20(riseTokenMetadata.token).totalSupply(); // Get collateral per TOKENRISE and debt per TOKENRISE
        uint8 collateralDecimals = IERC20Metadata(riseTokenMetadata.token).decimals();
        uint256 collateralPerRiseToken = calculateCollateralPerRiseToken(totalSupply, riseTokenMetadata.totalCollateralPlusFee, riseTokenMetadata.totalPendingFees, collateralDecimals);
        uint256 debtPerRiseToken = calculateDebtPerRiseToken(riseTokenMetadata.token, totalSupply, collateralDecimals);

        nav = calculateNAV(collateralPerRiseToken, debtPerRiseToken, collateralPrice, riseTokenMetadata.initialPrice, collateralDecimals);
    }

    /// @notice getCollateralAndFeeAmount splits collateral and fee amount
    function getCollateralAndFeeAmount(uint256 amount, uint256 feeInEther) internal pure returns (uint256 collateralAmount, uint256 feeAmount) {
        feeAmount = (amount * feeInEther) / 1 ether;
        collateralAmount = amount - feeAmount;
    }

    /// @notice swap swaps the inputToken to outputToken
    function swap(
        address swapContract, // The address of swap contract
        address inputToken, // The address of the token that we want to sell
        address outputToken, // The address of the output token that we want to buy
        uint256 maxInputAmount, // The maximum amount of input token that we want to sell
        uint256 outputAmount // The amount of output token that we want to buy
    ) internal returns (uint256 inputTokenSold) {
        IERC20(inputToken).safeApprove(swapContract, maxInputAmount); // Allow swap contract to spend the input token from the contract
        inputTokenSold = IRisedleSwap(swapContract).swap(inputToken, outputToken, maxInputAmount, outputAmount); // Swap inputToken to outputToken
        IERC20(inputToken).safeApprove(swapContract, 0); // Reset the approval
    }

    /// @notice getMintAmount returns the amount of TOKENRISE need to be minted
    function getMintAmount(
        uint256 nav, // The net asset value of TOKENRISE (e.g. 200 USDC is 200 * 1e6)
        uint256 collateralAmount, // The amount of the collateral (e.g. 1 ETH is 1e18)
        uint256 collateralPrice, // The price of the collateral (e.g. 4000 USDC is 4000 * 1e6)
        uint256 borrowAmount, // The amount of borrow (e.g 200 USDC is 200 * 1e6)
        uint8 collateralDecimals // The decimals of the collateral token (e.g. ETH have 18 decimals)
    ) internal pure returns (uint256 mintedAmount) {
        // Calculate the total investment
        uint256 totalInvestment = ((2 * collateralAmount * collateralPrice) / (10**collateralDecimals)) - borrowAmount; // totalInvestment = (2 x collateralValue) - borrowAmount
        mintedAmount = (totalInvestment * (10**collateralDecimals)) / nav; // Get minted amount
    }

    /// @notice Mint new TOKENRISE
    function mintRiseToken(
        address token, // The address of TOKENRISE
        address minter, // The minter address
        address recipient, // The TOKENRISE recipient
        uint256 amount // The Amount
    ) internal nonReentrant {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        if (riseTokenMetadata.maxTotalCollateral > 0) require(riseTokenMetadata.totalCollateralPlusFee + (2 * amount) < riseTokenMetadata.maxTotalCollateral, "!CIR"); // Cap is reached
        accrueInterest(); // Accrue interest
        uint256 nav = getNAV(token); // For example, If ETHRISE nav is 200 USDC, it will returns 200 * 1e6
        if (minter != address(this)) IERC20(riseTokenMetadata.collateral).safeTransferFrom(minter, address(this), amount); // Don't get WETH from the user
        (uint256 collateralAmount, uint256 feeAmount) = getCollateralAndFeeAmount(amount, riseTokenMetadata.feeInEther); // Get the collateral and fee amount
        riseTokens[riseTokenMetadata.token].totalCollateralPlusFee += ((2 * collateralAmount) + feeAmount); // Update the TOKENRISE metadata
        riseTokens[riseTokenMetadata.token].totalPendingFees += feeAmount;
        uint256 collateralPrice = IRisedleOracle(riseTokenMetadata.oracleContract).getPrice(); // Get the current price of collateral in term of vault underlying asset
        uint8 collateralDecimals = IERC20Metadata(riseTokenMetadata.collateral).decimals();
        uint256 maxCollateralPrice = collateralPrice + ((riseTokenMetadata.maxSwapSlippageInEther * collateralPrice) / 1 ether); // Maximum slippage from the oracle price; It can be +X% from the oracle price
        uint256 maxBorrowAmount = (collateralAmount * maxCollateralPrice) / (10**collateralDecimals); // Calculate the maximum borrow amount
        require(getTotalAvailableCash() > maxBorrowAmount, "!NES"); // Make sure we do have enough vault's underlying available
        uint256 borrowedAmount = swap(riseTokenMetadata.swapContract, underlyingToken, riseTokenMetadata.collateral, maxBorrowAmount, collateralAmount);
        setBorrowStates(token, borrowedAmount); // Set TOKENRISE debt states
        uint256 mintedAmount = getMintAmount(nav, collateralAmount, collateralPrice, borrowedAmount, collateralDecimals); // Calculate minted amount
        IRisedleERC20(token).mint(recipient, mintedAmount); // Transfer TOKENRISE to the caller
        emit RiseTokenMinted(recipient, token, mintedAmount);
    }

    /// @notice Mint new ETHRISE. The ETH will automatically wrapped to WETH first
    function mint(address token) external payable {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        require(riseTokenMetadata.isETH, "!TRNE"); // TOKENRISE is not ETH enabled
        require(msg.value > 0, "!EIZ"); // ETH is zero
        IWETH9(riseTokenMetadata.collateral).deposit{ value: msg.value }(); // Wrap the ETH to WETH
        mintRiseToken(token, address(this), msg.sender, msg.value); // Mint the ETHRISE token as the contract and send the ETHRISE to the user
    }

    /// @notice Mint new ETHRISE and sent minted token to the recipient
    function mint(address token, address recipient) external payable {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        require(riseTokenMetadata.isETH, "!TRNE"); // TOKENRISE is not ETH enabled
        require(msg.value > 0, "!EIZ"); // ETH is zero
        IWETH9(riseTokenMetadata.collateral).deposit{ value: msg.value }(); // Wrap the ETH to WETH
        mintRiseToken(token, address(this), recipient, msg.value); // Mint the ETHRISE token as the contract and send the ETHRISE to the user
    }

    /// @notice Mint new ERC20RISE
    function mint(address token, uint256 amount) external {
        mintRiseToken(token, msg.sender, msg.sender, amount);
    }

    /// @notice Mint new ERC20RISE with custom recipient
    function mint(
        address token,
        address recipient,
        uint256 amount
    ) external {
        mintRiseToken(token, msg.sender, recipient, amount);
    }

    /// @notice calculateLeverageRatio calculates leverage ratio
    function calculateLeverageRatio(
        uint256 collateralPerRiseToken,
        uint256 debtPerRiseToken,
        uint256 collateralPrice,
        uint256 etfInitialPrice,
        uint8 collateralDecimals
    ) internal pure returns (uint256 leverageRatioInEther) {
        uint256 collateralValuePerRiseToken = (collateralPerRiseToken * collateralPrice) / (10**collateralDecimals);
        uint256 nav = calculateNAV(collateralPerRiseToken, debtPerRiseToken, collateralPrice, etfInitialPrice, collateralDecimals);
        leverageRatioInEther = (collateralValuePerRiseToken * 1 ether) / nav;
    }

    /// @notice Get the leverage ratio
    function getLeverageRatioInEther(address token) external view returns (uint256 leverageRatioInEther) {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        if (riseTokenMetadata.feeInEther == 0) return 0; // Make sure the TOKENRISE is exists
        uint256 totalSupply = IERC20(riseTokenMetadata.token).totalSupply();
        uint8 collateralDecimals = IERC20Metadata(riseTokenMetadata.collateral).decimals();
        uint256 collateralPerRiseToken = calculateCollateralPerRiseToken(totalSupply, riseTokenMetadata.totalCollateralPlusFee, riseTokenMetadata.totalPendingFees, collateralDecimals);
        uint256 debtPerRiseToken = calculateDebtPerRiseToken(riseTokenMetadata.token, totalSupply, collateralDecimals);
        uint256 collateralPrice = IRisedleOracle(riseTokenMetadata.oracleContract).getPrice();
        leverageRatioInEther = calculateLeverageRatio(collateralPerRiseToken, debtPerRiseToken, collateralPrice, riseTokenMetadata.initialPrice, collateralDecimals);
    }

    /// @notice Run the rebalancing
    function rebalance(address token) external nonReentrant {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        accrueInterest(); // Accrue interest

        // Otherwise get the current leverage ratio
        uint256 totalSupply = IERC20(riseTokenMetadata.token).totalSupply();
        uint256 collateralPrice = IRisedleOracle(riseTokenMetadata.oracleContract).getPrice();
        uint8 collateralDecimals = IERC20Metadata(riseTokenMetadata.collateral).decimals();
        uint256 collateralPerRiseToken = calculateCollateralPerRiseToken(totalSupply, riseTokenMetadata.totalCollateralPlusFee, riseTokenMetadata.totalPendingFees, collateralDecimals);
        uint256 debtPerRiseToken = calculateDebtPerRiseToken(riseTokenMetadata.token, totalSupply, collateralDecimals);
        uint256 leverageRatioInEther = calculateLeverageRatio(collateralPerRiseToken, debtPerRiseToken, collateralPrice, riseTokenMetadata.initialPrice, collateralDecimals);
        uint256 nav = calculateNAV(collateralPerRiseToken, debtPerRiseToken, collateralPrice, riseTokenMetadata.initialPrice, collateralDecimals);
        require(leverageRatioInEther < riseTokenMetadata.minLeverageRatioInEther || leverageRatioInEther > riseTokenMetadata.maxLeverageRatioInEther, "!LRIR"); // Leverage ratio in range
        uint256 borrowOrRepayAmount = (riseTokenMetadata.rebalancingStepInEther * ((nav * totalSupply) / (10**collateralDecimals))) / 1 ether;
        uint256 collateralAmount = (borrowOrRepayAmount * (10**collateralDecimals)) / collateralPrice;

        // Leveraging up when: leverage ratio < min leverage ratio. Borrow more USDCa and Swap USDC to collateral token
        if (leverageRatioInEther < riseTokenMetadata.minLeverageRatioInEther) {
            uint256 maximumCollateralPrice = collateralPrice + ((riseTokenMetadata.maxSwapSlippageInEther * collateralPrice) / 1 ether);
            uint256 maxBorrowAmount = (collateralAmount * maximumCollateralPrice) / (10**collateralDecimals);
            if (maxBorrowAmount > riseTokenMetadata.maxRebalancingValue) {
                maxBorrowAmount = riseTokenMetadata.maxRebalancingValue;
            }
            uint256 borrowedAmount = swap(riseTokenMetadata.swapContract, underlyingToken, riseTokenMetadata.collateral, maxBorrowAmount, collateralAmount);
            setBorrowStates(token, borrowedAmount);
            riseTokens[riseTokenMetadata.token].totalCollateralPlusFee += collateralAmount;
        }

        // Leveraging down when: leverage ratio > max leverage ratio. Swap collateral to USDC and Repay the debt
        if (leverageRatioInEther > riseTokenMetadata.maxLeverageRatioInEther) {
            uint256 minimumCollateralPrice = collateralPrice - ((riseTokenMetadata.maxSwapSlippageInEther * collateralPrice) / 1 ether);
            uint256 maxCollateralAmount = (borrowOrRepayAmount * (10**collateralDecimals)) / minimumCollateralPrice;
            if (borrowOrRepayAmount > riseTokenMetadata.maxRebalancingValue) {
                maxCollateralAmount = (riseTokenMetadata.maxRebalancingValue * (10**collateralDecimals)) / minimumCollateralPrice;
            }
            uint256 collateralSoldAmount = swap(riseTokenMetadata.swapContract, riseTokenMetadata.collateral, underlyingToken, maxCollateralAmount, borrowOrRepayAmount);
            setRepayStates(token, borrowOrRepayAmount);
            riseTokens[riseTokenMetadata.token].totalCollateralPlusFee -= collateralSoldAmount;
        }

        emit RiseTokenRebalanced(msg.sender, leverageRatioInEther);
    }

    function updateRedeemStates(
        address token, // TOKENRISE address
        uint256 collateral, // Collateral amount
        uint256 fee // Fee amount
    ) internal {
        riseTokens[token].totalCollateralPlusFee -= collateral;
        riseTokens[token].totalPendingFees += fee;
    }

    function calculateRedeemAmount(RiseTokenMetadata memory riseTokenMetadata, uint256 amount) internal returns (uint256 redeemAmount) {
        uint256 totalSupply = IERC20(riseTokenMetadata.token).totalSupply();
        uint8 collateralDecimals = IERC20Metadata(riseTokenMetadata.collateral).decimals();
        uint256 collateralPrice = IRisedleOracle(riseTokenMetadata.oracleContract).getPrice();
        uint256 collateralPerRiseToken = calculateCollateralPerRiseToken(totalSupply, riseTokenMetadata.totalCollateralPlusFee, riseTokenMetadata.totalPendingFees, collateralDecimals);
        uint256 debtPerRiseToken = calculateDebtPerRiseToken(riseTokenMetadata.token, totalSupply, collateralDecimals);
        uint256 repayAmount = (debtPerRiseToken * amount) / (10**collateralDecimals);
        setRepayStates(riseTokenMetadata.token, repayAmount);
        uint256 collateralOwnedByUser = (amount * collateralPerRiseToken) / (10**collateralDecimals);
        uint256 minimumCollateralPrice = collateralPrice - ((riseTokenMetadata.maxSwapSlippageInEther * collateralPrice) / 1 ether);
        uint256 maxCollateralAmount = (((repayAmount * (10**collateralDecimals)) / ((collateralOwnedByUser * minimumCollateralPrice) / (10**collateralDecimals))) * collateralOwnedByUser) / (10**collateralDecimals);
        uint256 collateralSoldAmount = swap(riseTokenMetadata.swapContract, riseTokenMetadata.collateral, underlyingToken, maxCollateralAmount, repayAmount);
        uint256 feeAmount;
        (redeemAmount, feeAmount) = getCollateralAndFeeAmount(collateralOwnedByUser - collateralSoldAmount, riseTokenMetadata.feeInEther);
        updateRedeemStates(riseTokenMetadata.token, (collateralOwnedByUser - feeAmount), feeAmount);
    }

    /// @notice redeem Burn the TOKENRISE then send the collateral token to the sender
    function redeem(address token, uint256 amount) external nonReentrant {
        accrueInterest(); // Accrue interest
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        uint256 redeemAmount = calculateRedeemAmount(riseTokenMetadata, amount);
        IRisedleERC20(token).burn(msg.sender, amount);
        // Send the remaining collateral to the investor minus the fee
        if (riseTokenMetadata.isETH) {
            IWETH9(riseTokenMetadata.collateral).withdraw(redeemAmount);
            (bool success, ) = msg.sender.call{ value: redeemAmount }("");
            require(success, "!ERF"); // ETH Redeem failed
        } else {
            IERC20(riseTokenMetadata.collateral).safeTransfer(msg.sender, redeemAmount);
        }

        emit RiseTokenBurned(msg.sender, token, redeemAmount);
    }

    /// @notice collectPendingFees withdraws collected fees to the FEE_RECIPIENT address
    function collectPendingFees(address token) external {
        accrueInterest(); // Accrue interest
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        IERC20(riseTokenMetadata.collateral).safeTransfer(FEE_RECIPIENT, riseTokenMetadata.totalPendingFees);
        riseTokens[token].totalCollateralPlusFee -= riseTokenMetadata.totalPendingFees;
        riseTokens[token].totalPendingFees = 0;

        emit FeeCollected(msg.sender, riseTokenMetadata.totalPendingFees, FEE_RECIPIENT);
    }

    /// @notice Set the cap
    function setMaxTotalCollateral(address token, uint256 maxTotalCollateral) external onlyOwner {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        riseTokens[token].maxTotalCollateral = maxTotalCollateral;
        emit MaxTotalCollateralUpdated(token, maxTotalCollateral);
    }

    /// @notice Set the oracle contract
    function setOracleContract(address token, address newOracle) external onlyOwner {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        riseTokens[token].oracleContract = newOracle;
        emit OracleContractUpdated(token, newOracle);
    }

    /// @notice Set the swap contract
    function setSwapContract(address token, address newSwap) external onlyOwner {
        RiseTokenMetadata memory riseTokenMetadata = riseTokens[token];
        require(riseTokenMetadata.feeInEther > 0, "!RTNE"); // Make sure the TOKENRISE is exists
        riseTokens[token].swapContract = newSwap;
        emit SwapContractUpdated(token, newSwap);
    }

    /// @notice Receive ETH
    receive() external payable {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"feeRecipient","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collector","type":"address"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"address","name":"feeRecipient","type":"address"}],"name":"FeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"address","name":"newFeeRecipient","type":"address"}],"name":"FeeRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"previousVaultTotalOutstandingDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"previousVaultTotalPendingFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowRatePerSecondInEther","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"elapsedSeconds","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"interestAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalOutstandingDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalPendingFees","type":"uint256"}],"name":"InterestAccrued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"newMaxTotalCollateral","type":"uint256"}],"name":"MaxTotalCollateralUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"oracle","type":"address"}],"name":"OracleContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"uint256","name":"u","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"s1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"s2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"ParametersUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"riseToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemedAmount","type":"uint256"}],"name":"RiseTokenBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"RiseTokenCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"riseToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintedAmount","type":"uint256"}],"name":"RiseTokenMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousLeverageRatioInEther","type":"uint256"}],"name":"RiseTokenRebalanced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ExchangeRateInEther","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintedAmount","type":"uint256"}],"name":"SupplyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ExchangeRateInEther","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemedAmount","type":"uint256"}],"name":"SupplyRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"swap","type":"address"}],"name":"SwapContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"FEE_RECIPIENT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accrueInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"collectPendingFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectVaultPendingFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isETH","type":"bool"},{"internalType":"address","name":"tokenRiseAddress","type":"address"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"oracleContract","type":"address"},{"internalType":"address","name":"swapContract","type":"address"},{"internalType":"uint256","name":"maxSwapSlippageInEther","type":"uint256"},{"internalType":"uint256","name":"initialPrice","type":"uint256"},{"internalType":"uint256","name":"feeInEther","type":"uint256"},{"internalType":"uint256","name":"minLeverageRatioInEther","type":"uint256"},{"internalType":"uint256","name":"maxLeverageRatioInEther","type":"uint256"},{"internalType":"uint256","name":"maxRebalancingValue","type":"uint256"},{"internalType":"uint256","name":"rebalancingStepInEther","type":"uint256"}],"name":"create","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBorrowRatePerSecondInEther","outputs":[{"internalType":"uint256","name":"borrowRateInEther","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getCollateralPerRiseToken","outputs":[{"internalType":"uint256","name":"collateralPerRiseToken","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getDebtPerRiseToken","outputs":[{"internalType":"uint256","name":"debtPerRiseToken","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchangeRateInEther","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getLeverageRatioInEther","outputs":[{"internalType":"uint256","name":"leverageRatioInEther","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getMetadata","outputs":[{"components":[{"internalType":"bool","name":"isETH","type":"bool"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"oracleContract","type":"address"},{"internalType":"address","name":"swapContract","type":"address"},{"internalType":"uint256","name":"maxSwapSlippageInEther","type":"uint256"},{"internalType":"uint256","name":"initialPrice","type":"uint256"},{"internalType":"uint256","name":"feeInEther","type":"uint256"},{"internalType":"uint256","name":"totalCollateralPlusFee","type":"uint256"},{"internalType":"uint256","name":"totalPendingFees","type":"uint256"},{"internalType":"uint256","name":"minLeverageRatioInEther","type":"uint256"},{"internalType":"uint256","name":"maxLeverageRatioInEther","type":"uint256"},{"internalType":"uint256","name":"maxRebalancingValue","type":"uint256"},{"internalType":"uint256","name":"rebalancingStepInEther","type":"uint256"},{"internalType":"uint256","name":"maxTotalCollateral","type":"uint256"}],"internalType":"struct RiseTokenVault.RiseTokenMetadata","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getNAV","outputs":[{"internalType":"uint256","name":"nav","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getOutstandingDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSupplyRatePerSecondInEther","outputs":[{"internalType":"uint256","name":"supplyRateInEther","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAvailableCash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnderlying","outputs":[{"internalType":"address","name":"underlying","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUtilizationRateInEther","outputs":[{"internalType":"uint256","name":"utilizationRateInEther","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVaultParameters","outputs":[{"internalType":"uint256","name":"_optimalUtilizationRateInEther","type":"uint256"},{"internalType":"uint256","name":"_interestSlope1InEther","type":"uint256"},{"internalType":"uint256","name":"_interestSlope2InEther","type":"uint256"},{"internalType":"uint256","name":"_maxBorrowRatePerSecondInEther","type":"uint256"},{"internalType":"uint256","name":"_performanceFeeInEther","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxTotalDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"removeSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxTotalCollateral","type":"uint256"}],"name":"setMaxTotalCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"newOracle","type":"address"}],"name":"setOracleContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"newSwap","type":"address"}],"name":"setSwapContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setVaultMaxTotalDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"u","type":"uint256"},{"internalType":"uint256","name":"s1","type":"uint256"},{"internalType":"uint256","name":"s2","type":"uint256"},{"internalType":"uint256","name":"mr","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setVaultParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOutstandingDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPendingFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a0604052670c7d713b49da00006008556702c68af0bb140000600955670853a0d2313c0000600a556301e13380608052640bd014d7e6600b5567016345785d8a0000600c553480156200005257600080fd5b50604051620054d3380380620054d3833981016040819052620000759162000301565b83838383838381600390805190602001906200009392919062000171565b508051620000a990600490602084019062000171565b505050620000c6620000c06200011b60201b60201c565b6200011f565b6001600655600780546001600160a01b03199081166001600160a01b039485161790915542600d556000600e819055600f819055601280549092169290931691909117905560115550620003cd945050505050565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200017f9062000390565b90600052602060002090601f016020900481019282620001a35760008555620001ee565b82601f10620001be57805160ff1916838001178555620001ee565b82800160010185558215620001ee579182015b82811115620001ee578251825591602001919060010190620001d1565b50620001fc92915062000200565b5090565b5b80821115620001fc576000815560010162000201565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200023f57600080fd5b81516001600160401b03808211156200025c576200025c62000217565b604051601f8301601f19908116603f0116810190828211818310171562000287576200028762000217565b81604052838152602092508683858801011115620002a457600080fd5b600091505b83821015620002c85785820183015181830184015290820190620002a9565b83821115620002da5760008385830101525b9695505050505050565b80516001600160a01b0381168114620002fc57600080fd5b919050565b600080600080608085870312156200031857600080fd5b84516001600160401b03808211156200033057600080fd5b6200033e888389016200022d565b955060208701519150808211156200035557600080fd5b5062000364878288016200022d565b9350506200037560408601620002e4565b91506200038560608601620002e4565b905092959194509250565b600181811c90821680620003a557607f821691505b60208210811415620003c757634e487b7160e01b600052602260045260246000fd5b50919050565b6080516150e3620003f060003960008181613d800152613e2c01526150e36000f3fe6080604052600436106102b25760003560e01c8063715018a611610175578063a927de78116100dc578063e74b981b11610095578063ee1fe2ad1161006f578063ee1fe2ad1461087f578063f2fde38b14610892578063f76f5db5146108b2578063fd1b8498146108c757600080fd5b8063e74b981b1461081f578063e7a357181461083f578063ebd090541461085f57600080fd5b8063a927de7814610744578063acd4b00a14610759578063c6b5f6e214610779578063c6c3bbe614610799578063dc54a8ee146107b9578063dd62ed3e146107d957600080fd5b806395d89b411161012e57806395d89b411461069c5780639816f473146106b1578063a2fcc7ec146106cf578063a457c2d7146106ef578063a6afed951461070f578063a9059cbb1461072457600080fd5b8063715018a6146105f457806371a6cab71461060957806373f2cd8e1461061f578063859203e31461063f5780638da5cb5b14610655578063942c7cb41461068757600080fd5b8063298cbf261161021957806340c10f19116101d257806340c10f19146105125780634f4c25561461053257806363d4f58714610576578063695b84c4146105965780636a627842146105ab57806370a08231146105be57600080fd5b8063298cbf26146104495780632a50c1461461045e5780632a65983a1461048b578063313ce567146104ab57806339509351146104d257806340753a76146104f257600080fd5b806318160ddd1161026b57806318160ddd146103945780631e9a6950146103a95780631ea6cabc146103c957806321c28191146103e957806323b872dd1461040957806326bb0e8e1461042957600080fd5b806306fdde03146102be578063095ea7b3146102e95780630d7c759114610319578063109e62ea1461033c57806311ebf36d14610352578063179ddcdd1461037457600080fd5b366102b957005b600080fd5b3480156102ca57600080fd5b506102d36108e7565b6040516102e09190614aec565b60405180910390f35b3480156102f557600080fd5b50610309610304366004614b36565b610979565b60405190151581526020016102e0565b34801561032557600080fd5b5061032e610990565b6040519081526020016102e0565b34801561034857600080fd5b5061032e600f5481565b34801561035e57600080fd5b5061037261036d366004614b60565b6109f8565b005b34801561038057600080fd5b5061032e61038f366004614b60565b610bc6565b3480156103a057600080fd5b5060025461032e565b3480156103b557600080fd5b506103726103c4366004614b36565b610e33565b3480156103d557600080fd5b5061032e6103e4366004614b60565b61111e565b3480156103f557600080fd5b50610372610404366004614b60565b6111ac565b34801561041557600080fd5b50610309610424366004614b7b565b61174a565b34801561043557600080fd5b50610372610444366004614bb7565b6117f6565b34801561045557600080fd5b5061032e61196e565b34801561046a57600080fd5b5061047e610479366004614b60565b61198a565b6040516102e09190614bea565b34801561049757600080fd5b506103726104a6366004614ce1565b611afe565b3480156104b757600080fd5b506104c0611e85565b60405160ff90911681526020016102e0565b3480156104de57600080fd5b506103096104ed366004614b36565b611ef8565b3480156104fe57600080fd5b5061037261050d366004614d89565b611f34565b34801561051e57600080fd5b5061037261052d366004614b36565b612063565b34801561053e57600080fd5b50600854600954600a54600b54600c54604080519586526020860194909452928401919091526060830152608082015260a0016102e0565b34801561058257600080fd5b50610372610591366004614da2565b612073565b3480156105a257600080fd5b5061037261210e565b6103726105b9366004614b60565b61218c565b3480156105ca57600080fd5b5061032e6105d9366004614b60565b6001600160a01b031660009081526020819052604090205490565b34801561060057600080fd5b50610372612352565b34801561061557600080fd5b5061032e60115481565b34801561062b57600080fd5b5061032e61063a366004614b60565b612388565b34801561064b57600080fd5b5061032e600e5481565b34801561066157600080fd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016102e0565b34801561069357600080fd5b5061032e6125e9565b3480156106a857600080fd5b506102d3612664565b3480156106bd57600080fd5b506007546001600160a01b031661066f565b3480156106db57600080fd5b5061032e6106ea366004614b60565b612673565b3480156106fb57600080fd5b5061030961070a366004614b36565b612842565b34801561071b57600080fd5b506103726128db565b34801561073057600080fd5b5061030961073f366004614b36565b6129a2565b34801561075057600080fd5b5061032e6129af565b34801561076557600080fd5b50610372610774366004614bb7565b612a40565b34801561078557600080fd5b5061032e610794366004614b60565b612bb8565b3480156107a557600080fd5b506103726107b4366004614b7b565b612d80565b3480156107c557600080fd5b506103726107d4366004614d89565b612d91565b3480156107e557600080fd5b5061032e6107f4366004614bb7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561082b57600080fd5b5061037261083a366004614b60565b612dc0565b34801561084b57600080fd5b5061037261085a366004614d89565b612e3f565b34801561086b57600080fd5b5060125461066f906001600160a01b031681565b61037261088d366004614bb7565b612efe565b34801561089e57600080fd5b506103726108ad366004614b60565b6130c4565b3480156108be57600080fd5b5061032e61315f565b3480156108d357600080fd5b506103726108e2366004614b36565b613178565b6060600380546108f690614ddd565b80601f016020809104026020016040519081016040528092919081815260200182805461092290614ddd565b801561096f5780601f106109445761010080835404028352916020019161096f565b820191906000526020600020905b81548152906001019060200180831161095257829003601f168201915b5050505050905090565b60006109863384846132f2565b5060015b92915050565b60008061099c60025490565b9050806109b257670de0b6b3a764000091505090565b60006109bc6129af565b90506000600e54826109ce9190614e2e565b90506000836109e583670de0b6b3a7640000614e46565b6109ef9190614e7b565b95945050505050565b610a006128db565b6001600160a01b0380821660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290610afc5760405162461bcd60e51b8152600401610af390614e8f565b60405180910390fd5b6012546101208201516040830151610b22926001600160a01b0391821692911690613416565b6101208101516001600160a01b03831660009081526014602052604081206007018054909190610b53908490614eae565b90915550506001600160a01b0382811660009081526014602090815260408083206008019290925561012084015160125483513381529283019190915290921682820152517f36119f4f28ae3384ed31589f21ec2992cb0ebe53b11c79a24466ee74471764ed9181900360600190a15050565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c0840152909190610cab5750600092915050565b600081606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d139190614ec5565b9050600082602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7d9190614ec5565b9050600083602001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de79190614ede565b90506000610e018386610100015187610120015185613479565b90506000610e14866020015185856134bd565b9050610e278282878960c001518761353d565b98975050505050505050565b60026006541415610e565760405162461bcd60e51b8152600401610af390614f01565b6002600655610e636128db565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290610f565760405162461bcd60e51b8152600401610af390614e8f565b6000610f628284613583565b604051632770a7eb60e21b8152336004820152602481018590529091506001600160a01b03851690639dc29fac90604401600060405180830381600087803b158015610fad57600080fd5b505af1158015610fc1573d6000803e3d6000fd5b505050508160000151156110ba5781604001516001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040161100191815260200190565b600060405180830381600087803b15801561101b57600080fd5b505af115801561102f573d6000803e3d6000fd5b50506040516000925033915083908381818185875af1925050503d8060008114611075576040519150601f19603f3d011682016040523d82523d6000602084013e61107a565b606091505b50509050806110b45760405162461bcd60e51b8152600401610af39060208082526004908201526310a2a92360e11b604082015260600190565b506110d3565b60408201516110d3906001600160a01b03163383613416565b6040518181526001600160a01b0385169033907f547518a7214f42d72dccc4ed54426ba50f889c24bb4d9766443e899a123381b39060200160405180910390a3505060016006555050565b6000600e546000141561113357506000919050565b600061113d61384b565b6001600160a01b03841660009081526013602052604081205491925090611165908390614e46565b9050670de0b6b3a7640000600061117c8284614f38565b1561118857600161118b565b60005b60ff166111988385614e7b565b6111a29190614e2e565b9695505050505050565b600260065414156111cf5760405162461bcd60e51b8152600401610af390614f01565b600260068181556001600160a01b0380841660009081526014602090815260409182902082516101e081018452815460ff811615158252610100908190048616938201939093526001820154851693810193909352948501548316606083015260038501549092166080820152600484015460a0820152600584015460c08201529183015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906112c75760405162461bcd60e51b8152600401610af390614e8f565b6112cf6128db565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611313573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113379190614ec5565b9050600082606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561137d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a19190614ec5565b9050600083604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140b9190614ede565b905060006114258486610100015187610120015185613479565b90506000611438866020015186856134bd565b9050600061144d8383878a60c0015188613892565b905060006114628484888b60c001518961353d565b905087610140015182108061147b575087610160015182115b6114af5760405162461bcd60e51b815260206004820152600560248201526410a62924a960d91b6044820152606401610af3565b6000670de0b6b3a76400006114c587600a615030565b6114cf8a85614e46565b6114d99190614e7b565b8a6101a001516114e99190614e46565b6114f39190614e7b565b905060008761150388600a615030565b61150d9084614e46565b6115179190614e7b565b9050896101400151841015611600576000670de0b6b3a7640000898c60a001516115419190614e46565b61154b9190614e7b565b611555908a614e2e565b9050600061156489600a615030565b61156e8385614e46565b6115789190614e7b565b90508b610180015181111561158f57506101808b01515b60006115bb8d60800151600760009054906101000a90046001600160a01b03168f6040015185886138e4565b90506115c78e82613993565b6020808e01516001600160a01b0316600090815260149091526040812060070180548692906115f7908490614e2e565b90915550505050505b896101600151841115611703576000670de0b6b3a7640000898c60a001516116289190614e46565b6116329190614e7b565b61163c908a614eae565b905060008161164c8a600a615030565b6116569086614e46565b6116609190614e7b565b90508b6101800151841115611698578161167b8a600a615030565b8d610180015161168b9190614e46565b6116959190614e7b565b90505b60808c015160408d01516007546000926116be9290916001600160a01b031685896138e4565b90506116ca8e86613a35565b6020808e01516001600160a01b0316600090815260149091526040812060070180548392906116fa908490614eae565b90915550505050505b60405184815233907fdf85796b4c3419ec22e630b81a8766863bb75964edc1c7869986126e66f633449060200160405180910390a250506001600655505050505050505050565b6000611757848484613b40565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156117dc5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610af3565b6117e985338584036132f2565b60019150505b9392505050565b6005546001600160a01b031633146118205760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906119135760405162461bcd60e51b8152600401610af390614e8f565b6001600160a01b0383811660008181526014602052604080822060030180546001600160a01b0319169487169485179055517f28c4fd18fb488de9f00ed376c22a3a7d2bbadabfaec7ab26651c824676f6fd4b9190a3505050565b60008061197961315f565b905061198481613d0e565b91505090565b611a29604051806101e0016040528060001515815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b506001600160a01b0390811660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e083015260078301549082015260088201546101208201526009820154610140820152600a820154610160820152600b820154610180820152600c8201546101a0820152600d909101546101c082015290565b6005546001600160a01b03163314611b285760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b03808c1660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c08201529015611c325760405162461bcd60e51b815260206004820152600360248201526221414560e81b6044820152606401610af3565b604051806101e001604052808e151581526020018d6001600160a01b031681526020018c6001600160a01b031681526020018b6001600160a01b031681526020018a6001600160a01b0316815260200189815260200188815260200187815260200160008152602001600081526020018681526020018581526020018481526020018381526020016000815250601460008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060808201518160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a0820151816004015560c0820151816005015560e0820151816006015561010082015181600701556101208201518160080155610140820151816009015561016082015181600a015561018082015181600b01556101a082015181600c01556101c082015181600d0155905050336001600160a01b03167f2a2b0348f99631bd5cb9665e0b2341476d6e9725bc1cc07c04f3c78fa958ad1f8d604051611e6e91906001600160a01b0391909116815260200190565b60405180910390a250505050505050505050505050565b6007546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015611ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef39190614ede565b905090565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610986918590611f2f908690614e2e565b6132f2565b60026006541415611f575760405162461bcd60e51b8152600401610af390614f01565b6002600655611f646128db565b60115415611fc55760115481600e54611f7b6129af565b611f859190614e2e565b611f8f9190614e2e565b10611fc55760405162461bcd60e51b8152600401610af39060208082526004908201526310a6a1a960e11b604082015260600190565b6000611fcf610990565b9050600081611fe684670de0b6b3a7640000614e46565b611ff09190614e7b565b60075490915061200b906001600160a01b0316333086613e70565b6120153382613ea8565b604080518481526020810184905290810182905233907f85a85f897cc05e4f2226d4f0a00a86d8c091e7b9af9155d98f54cf9bdcb96934906060015b60405180910390a25050600160065550565b61206f82333384613f87565b5050565b6005546001600160a01b0316331461209d5760405162461bcd60e51b8152600401610af39061503f565b60088590556009849055600a839055600b829055600c8190556040805186815260208101869052908101849052606081018390526080810182905233907f307727c989f3c87a872f36c0c665dec093dfee07d03e13be7d3d624637f436819060a00160405180910390a25050505050565b6121166128db565b600f54601254600754612136916001600160a01b03918216911683613416565b6000600f5560125460408051338152602081018490526001600160a01b03909216908201527f36119f4f28ae3384ed31589f21ec2992cb0ebe53b11c79a24466ee74471764ed906060015b60405180910390a150565b6001600160a01b0380821660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c08201529061227f5760405162461bcd60e51b8152600401610af390614e8f565b80516122b55760405162461bcd60e51b81526020600482015260056024820152642154524e4560d81b6044820152606401610af3565b600034116122ee5760405162461bcd60e51b8152600401610af39060208082526004908201526310a2a4ad60e11b604082015260600190565b80604001516001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561232d57600080fd5b505af1158015612341573d6000803e3d6000fd5b505050505061206f82303334613f87565b6005546001600160a01b0316331461237c5760405162461bcd60e51b8152600401610af39061503f565b6123866000614451565b565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c084015290919061246d5750600092915050565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d59190614ec5565b9050600082604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561251b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253f9190614ede565b905060006125598385610100015186610120015185613479565b9050600061256c856020015185856134bd565b9050600085606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d69190614ec5565b9050610e278383838960c0015188613892565b6000806125f461315f565b9050600061260182613d0e565b90506000600c54670de0b6b3a764000061261b9190614eae565b90506000670de0b6b3a76400006126328385614e46565b61263c9190614e7b565b9050670de0b6b3a76400006126518286614e46565b61265b9190614e7b565b94505050505090565b6060600480546108f690614ddd565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c08401529091906127585750600092915050565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561279c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c09190614ec5565b9050600082602001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612806573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061282a9190614ede565b90506109ef8284610100015185610120015184613479565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156128c45760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610af3565b6128d133858584036132f2565b5060019392505050565b600d544290808214156128ec575050565b600e54600f5460006128fc61196e565b9050600061290a8587614eae565b9050600061291b600e5484846144a3565b905061292781886144e6565b600e54600f5460408051898152602081018b9052908101889052606081018790526080810186905260a0810185905260c0810184905260e08101929092526101008201527f6359a1d821ddb244007da3e8ee241ce7b45d540a1896549f82566c50c68d7c60906101200160405180910390a150505050505050565b6000610986338484613b40565b6007546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156129fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a209190614ec5565b905080600f5410612a3357600091505090565b600f546119849082614eae565b6005546001600160a01b03163314612a6a5760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290612b5d5760405162461bcd60e51b8152600401610af390614e8f565b6001600160a01b0383811660008181526014602052604080822060020180546001600160a01b0319169487169485179055517fbf7ec739eb17989ec37b8022950e7d1780f24bd2f029fe363f8320b6b6042f7c9190a3505050565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c0840152909190612c9d5750600092915050565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d059190614ec5565b9050600082602001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6f9190614ede565b90506109ef836020015183836134bd565b612d8c83338484613f87565b505050565b6005546001600160a01b03163314612dbb5760405162461bcd60e51b8152600401610af39061503f565b601155565b6005546001600160a01b03163314612dea5760405162461bcd60e51b8152600401610af39061503f565b601280546001600160a01b0319166001600160a01b0383169081179091556040805133815260208101929092527faaebcf1bfa00580e41d966056b48521fa9f202645c86d4ddf28113e617c1b1d39101612181565b60026006541415612e625760405162461bcd60e51b8152600401610af390614f01565b6002600655612e6f6128db565b6000612e79610990565b90506000670de0b6b3a7640000612e908484614e46565b612e9a9190614e7b565b600754909150612eb4906001600160a01b03163383613416565b612ebe3384614542565b604080518481526020810184905290810182905233907fc30dcbcc543321ea79e9955ec689be197278979aa6117ad1b66bebf48d0f204090606001612051565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290612ff15760405162461bcd60e51b8152600401610af390614e8f565b80516130275760405162461bcd60e51b81526020600482015260056024820152642154524e4560d81b6044820152606401610af3565b600034116130605760405162461bcd60e51b8152600401610af39060208082526004908201526310a2a4ad60e11b604082015260600190565b80604001516001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561309f57600080fd5b505af11580156130b3573d6000803e3d6000fd5b5050505050612d8c83308434613f87565b6005546001600160a01b031633146130ee5760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0381166131535760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610af3565b61315c81614451565b50565b60008061316a6129af565b905061198481600e54614690565b6005546001600160a01b031633146131a25760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906132955760405162461bcd60e51b8152600401610af390614e8f565b6001600160a01b03831660008181526014602052604090819020600d01849055517f5084e158024653e5c1fb3043afcfdfb3265f039c5bb0a81eace8ad704445002d906132e59085815260200190565b60405180910390a2505050565b6001600160a01b0383166133545760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610af3565b6001600160a01b0382166133b55760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610af3565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6040516001600160a01b038316602482015260448101829052612d8c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526146e9565b600084613488575060006134b5565b8461349483600a615030565b61349e8587614eae565b6134a89190614e46565b6134b29190614e7b565b90505b949350505050565b6000826134cc575060006117ef565b60006134d78561111e565b9050806134e85760009150506117ef565b60006134f584600a615030565b6134ff9083614e46565b90508461350c8183614f38565b1561351857600161351b565b60005b60ff166135288284614e7b565b6135329190614e2e565b979650505050505050565b600085158061354a575084155b156135565750816109ef565b600061356383600a615030565b61356d8689614e46565b6135779190614e7b565b90506135328682614eae565b60008083602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ec9190614ec5565b9050600084604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613632573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136569190614ede565b9050600085606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561369c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136c09190614ec5565b905060006136da8488610100015189610120015186613479565b905060006136ed886020015186866134bd565b905060006136fc85600a615030565b6137068984614e46565b6137109190614e7b565b9050613720896020015182613a35565b600061372d86600a615030565b613737858b614e46565b6137419190614e7b565b90506000670de0b6b3a7640000868c60a0015161375e9190614e46565b6137689190614e7b565b6137729087614eae565b9050600061378188600a615030565b8361378d8a600a615030565b6137978587614e46565b6137a19190614e7b565b6137ac8b600a615030565b6137b69088614e46565b6137c09190614e7b565b6137ca9190614e46565b6137d49190614e7b565b60808d015160408e01516007549293506000926137fd9291906001600160a01b031685896138e4565b9050600061381861380e8387614eae565b8f60e001516147bb565b809250819d50505061383a8e6020015182876138349190614eae565b836147f0565b505050505050505050505092915050565b6000600e546000148061385e5750601054155b156138705750670de0b6b3a764000090565b601054600e5461388890670de0b6b3a7640000614e46565b611ef39190614e7b565b6000806138a083600a615030565b6138aa8689614e46565b6138b49190614e7b565b905060006138c5888888888861353d565b9050806138da83670de0b6b3a7640000614e46565b610e279190614e7b565b60006138fa6001600160a01b0386168785614855565b604051637f0148ab60e11b81526001600160a01b0386811660048301528581166024830152604482018590526064820184905287169063fe029156906084016020604051808303816000875af1158015613958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061397c9190614ec5565b90506109ef6001600160a01b038616876000614855565b600061399d61384b565b905081600e60008282546139b19190614e2e565b9091555060009050816139cc84670de0b6b3a7640000614e46565b6139d69190614e7b565b905080601060008282546139ea9190614e2e565b90915550506001600160a01b038416600090815260136020526040902054613a13908290614e2e565b6001600160a01b03909416600090815260136020526040902093909355505050565b6000613a3f61384b565b9050600e54821115613a55576000600e55613a6d565b81600e6000828254613a679190614eae565b90915550505b600081613a8284670de0b6b3a7640000614e46565b613a8c9190614e7b565b9050601054811115613aa2576000601055613aba565b8060106000828254613ab49190614eae565b90915550505b6001600160a01b038416600090815260136020526040902054811115613b0c576001600160a01b038416600090815260136020526040812080548290613b01908290614eae565b90915550613b3a9050565b6001600160a01b03841660009081526013602052604081208054839290613b34908490614eae565b90915550505b50505050565b6001600160a01b038316613ba45760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610af3565b6001600160a01b038216613c065760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610af3565b6001600160a01b03831660009081526020819052604090205481811015613c7e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610af3565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290613cb5908490614e2e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613d0191815260200190565b60405180910390a3613b3a565b6000670de0b6b3a76400008210613d27575050600b5490565b6008548211613da557600854600090613d4884670de0b6b3a7640000614e46565b613d529190614e7b565b90506000670de0b6b3a764000060095483613d6d9190614e46565b613d779190614e7b565b905060006109ef7f000000000000000000000000000000000000000000000000000000000000000083614e7b565b600060085483613db59190614eae565b90506000613dcb84670de0b6b3a7640000614eae565b9050600081613de284670de0b6b3a7640000614e46565b613dec9190614e7b565b90506000670de0b6b3a7640000600a5483613e079190614e46565b613e119190614e7b565b9050600081600954613e239190614e2e565b90506000613e517f000000000000000000000000000000000000000000000000000000000000000083614e7b565b9050600b548110613532575050600b549695505050505050565b919050565b6040516001600160a01b0380851660248301528316604482015260648101829052613b3a9085906323b872dd60e01b90608401613442565b6001600160a01b038216613efe5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610af3565b8060026000828254613f109190614e2e565b90915550506001600160a01b03821660009081526020819052604081208054839290613f3d908490614e2e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60026006541415613faa5760405162461bcd60e51b8152600401610af390614f01565b600260068181556001600160a01b0380871660009081526014602090815260409182902082516101e081018452815460ff811615158252610100908190048616938201939093526001820154851693810193909352948501548316606083015260038501549092166080820152600484015460a0820152600584015460c08201529183015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906140a25760405162461bcd60e51b8152600401610af390614e8f565b6101c081015115614104576101c08101516140be836002614e46565b8261010001516140ce9190614e2e565b106141045760405162461bcd60e51b8152600401610af39060208082526004908201526310a1a4a960e11b604082015260600190565b61410c6128db565b600061411786610bc6565b90506001600160a01b0385163014614143576040820151614143906001600160a01b0316863086613e70565b600080614154858560e001516147bb565b909250905080614165836002614e46565b61416f9190614e2e565b6020808601516001600160a01b03166000908152601490915260408120600701805490919061419f908490614e2e565b90915550506020808501516001600160a01b0316600090815260149091526040812060080180548392906141d4908490614e2e565b92505081905550600084606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561421f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142439190614ec5565b9050600085604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614289573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142ad9190614ede565b90506000670de0b6b3a7640000838860a001516142ca9190614e46565b6142d49190614e7b565b6142de9084614e2e565b905060006142ed83600a615030565b6142f78388614e46565b6143019190614e7b565b90508061430c6129af565b116143425760405162461bcd60e51b8152600401610af390602080825260049082015263214e455360e01b604082015260600190565b600061436e8960800151600760009054906101000a90046001600160a01b03168b60400151858b6138e4565b905061437a8d82613993565b6000614389898988858961496a565b6040516340c10f1960e01b81526001600160a01b038e8116600483015260248201839052919250908f16906340c10f1990604401600060405180830381600087803b1580156143d757600080fd5b505af11580156143eb573d6000803e3d6000fd5b505050508d6001600160a01b03168c6001600160a01b03167fede1f310f6f94790fc59194108fa63c31d34618eb55c66f142a8eb2088770c4c8360405161443491815260200190565b60405180910390a350506001600655505050505050505050505050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008315806144b0575082155b806144b9575081155b156144c6575060006117ef565b6000670de0b6b3a7640000856144dc8587614e46565b6109e59190614e46565b6000670de0b6b3a764000083600c546144ff9190614e46565b6145099190614e7b565b905082600e600082825461451d9190614e2e565b9250508190555080600f60008282546145369190614e2e565b909155505050600d5550565b6001600160a01b0382166145a25760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610af3565b6001600160a01b038216600090815260208190526040902054818110156146165760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610af3565b6001600160a01b0383166000908152602081905260408120838303905560028054849290614645908490614eae565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60008161469f5750600061098a565b821580156146ad5750600082115b156146c15750670de0b6b3a764000061098a565b60006146cd8484614e2e565b6146df84670de0b6b3a7640000614e46565b6134b59190614e7b565b600061473e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166149c59092919063ffffffff16565b805190915015612d8c578080602001905181019061475c9190615074565b612d8c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610af3565b600080670de0b6b3a76400006147d18486614e46565b6147db9190614e7b565b90506147e78185614eae565b91509250929050565b6001600160a01b0383166000908152601460205260408120600701805484929061481b908490614eae565b90915550506001600160a01b0383166000908152601460205260408120600801805483929061484b908490614e2e565b9091555050505050565b8015806148cf5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156148a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148cd9190614ec5565b155b61493a5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610af3565b6040516001600160a01b038316602482015260448101829052612d8c90849063095ea7b360e01b90606401613442565b6000808361497984600a615030565b86614985896002614e46565b61498f9190614e46565b6149999190614e7b565b6149a39190614eae565b9050866149b184600a615030565b6149bb9083614e46565b6135329190614e7b565b60606134b5848460008585843b614a1e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610af3565b600080866001600160a01b03168587604051614a3a9190615091565b60006040518083038185875af1925050503d8060008114614a77576040519150601f19603f3d011682016040523d82523d6000602084013e614a7c565b606091505b509150915061353282828660608315614a965750816117ef565b825115614aa65782518084602001fd5b8160405162461bcd60e51b8152600401610af39190614aec565b60005b83811015614adb578181015183820152602001614ac3565b83811115613b3a5750506000910152565b6020815260008251806020840152614b0b816040850160208701614ac0565b601f01601f19169190910160400192915050565b80356001600160a01b0381168114613e6b57600080fd5b60008060408385031215614b4957600080fd5b614b5283614b1f565b946020939093013593505050565b600060208284031215614b7257600080fd5b6117ef82614b1f565b600080600060608486031215614b9057600080fd5b614b9984614b1f565b9250614ba760208501614b1f565b9150604084013590509250925092565b60008060408385031215614bca57600080fd5b614bd383614b1f565b9150614be160208401614b1f565b90509250929050565b8151151581526101e081016020830151614c0f60208401826001600160a01b03169052565b506040830151614c2a60408401826001600160a01b03169052565b506060830151614c4560608401826001600160a01b03169052565b506080830151614c6060808401826001600160a01b03169052565b5060a0838101519083015260c0808401519083015260e08084015190830152610100808401519083015261012080840151908301526101408084015190830152610160808401519083015261018080840151908301526101a080840151908301526101c092830151929091019190915290565b801515811461315c57600080fd5b6000806000806000806000806000806000806101808d8f031215614d0457600080fd5b8c35614d0f81614cd3565b9b50614d1d60208e01614b1f565b9a50614d2b60408e01614b1f565b9950614d3960608e01614b1f565b9850614d4760808e01614b1f565b9b9e9a9d50989b979a9960a0890135995060c08901359860e0810135985061010081013597506101208101359650610140810135955061016001359350915050565b600060208284031215614d9b57600080fd5b5035919050565b600080600080600060a08688031215614dba57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600181811c90821680614df157607f821691505b60208210811415614e1257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115614e4157614e41614e18565b500190565b6000816000190483118215151615614e6057614e60614e18565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614e8a57614e8a614e65565b500490565b6020808252600590820152642152544e4560d81b604082015260600190565b600082821015614ec057614ec0614e18565b500390565b600060208284031215614ed757600080fd5b5051919050565b600060208284031215614ef057600080fd5b815160ff811681146117ef57600080fd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082614f4757614f47614e65565b500690565b600181815b80851115614f87578160001904821115614f6d57614f6d614e18565b80851615614f7a57918102915b93841c9390800290614f51565b509250929050565b600082614f9e5750600161098a565b81614fab5750600061098a565b8160018114614fc15760028114614fcb57614fe7565b600191505061098a565b60ff841115614fdc57614fdc614e18565b50506001821b61098a565b5060208310610133831016604e8410600b841016171561500a575081810a61098a565b6150148383614f4c565b806000190482111561502857615028614e18565b029392505050565b60006117ef60ff841683614f8f565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561508657600080fd5b81516117ef81614cd3565b600082516150a3818460208701614ac0565b919091019291505056fea264697066735822122087643f065a980a4a954bc2572705531040ff2c5f36f37db464c1f0ea5bd01b6764736f6c634300080b0033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc800000000000000000000000056b4a9675c52144c99f676835e83d5625cb47202000000000000000000000000000000000000000000000000000000000000001552697365646c65205661756c742045544855534443000000000000000000000000000000000000000000000000000000000000000000000000000000000000097276455448555344430000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102b25760003560e01c8063715018a611610175578063a927de78116100dc578063e74b981b11610095578063ee1fe2ad1161006f578063ee1fe2ad1461087f578063f2fde38b14610892578063f76f5db5146108b2578063fd1b8498146108c757600080fd5b8063e74b981b1461081f578063e7a357181461083f578063ebd090541461085f57600080fd5b8063a927de7814610744578063acd4b00a14610759578063c6b5f6e214610779578063c6c3bbe614610799578063dc54a8ee146107b9578063dd62ed3e146107d957600080fd5b806395d89b411161012e57806395d89b411461069c5780639816f473146106b1578063a2fcc7ec146106cf578063a457c2d7146106ef578063a6afed951461070f578063a9059cbb1461072457600080fd5b8063715018a6146105f457806371a6cab71461060957806373f2cd8e1461061f578063859203e31461063f5780638da5cb5b14610655578063942c7cb41461068757600080fd5b8063298cbf261161021957806340c10f19116101d257806340c10f19146105125780634f4c25561461053257806363d4f58714610576578063695b84c4146105965780636a627842146105ab57806370a08231146105be57600080fd5b8063298cbf26146104495780632a50c1461461045e5780632a65983a1461048b578063313ce567146104ab57806339509351146104d257806340753a76146104f257600080fd5b806318160ddd1161026b57806318160ddd146103945780631e9a6950146103a95780631ea6cabc146103c957806321c28191146103e957806323b872dd1461040957806326bb0e8e1461042957600080fd5b806306fdde03146102be578063095ea7b3146102e95780630d7c759114610319578063109e62ea1461033c57806311ebf36d14610352578063179ddcdd1461037457600080fd5b366102b957005b600080fd5b3480156102ca57600080fd5b506102d36108e7565b6040516102e09190614aec565b60405180910390f35b3480156102f557600080fd5b50610309610304366004614b36565b610979565b60405190151581526020016102e0565b34801561032557600080fd5b5061032e610990565b6040519081526020016102e0565b34801561034857600080fd5b5061032e600f5481565b34801561035e57600080fd5b5061037261036d366004614b60565b6109f8565b005b34801561038057600080fd5b5061032e61038f366004614b60565b610bc6565b3480156103a057600080fd5b5060025461032e565b3480156103b557600080fd5b506103726103c4366004614b36565b610e33565b3480156103d557600080fd5b5061032e6103e4366004614b60565b61111e565b3480156103f557600080fd5b50610372610404366004614b60565b6111ac565b34801561041557600080fd5b50610309610424366004614b7b565b61174a565b34801561043557600080fd5b50610372610444366004614bb7565b6117f6565b34801561045557600080fd5b5061032e61196e565b34801561046a57600080fd5b5061047e610479366004614b60565b61198a565b6040516102e09190614bea565b34801561049757600080fd5b506103726104a6366004614ce1565b611afe565b3480156104b757600080fd5b506104c0611e85565b60405160ff90911681526020016102e0565b3480156104de57600080fd5b506103096104ed366004614b36565b611ef8565b3480156104fe57600080fd5b5061037261050d366004614d89565b611f34565b34801561051e57600080fd5b5061037261052d366004614b36565b612063565b34801561053e57600080fd5b50600854600954600a54600b54600c54604080519586526020860194909452928401919091526060830152608082015260a0016102e0565b34801561058257600080fd5b50610372610591366004614da2565b612073565b3480156105a257600080fd5b5061037261210e565b6103726105b9366004614b60565b61218c565b3480156105ca57600080fd5b5061032e6105d9366004614b60565b6001600160a01b031660009081526020819052604090205490565b34801561060057600080fd5b50610372612352565b34801561061557600080fd5b5061032e60115481565b34801561062b57600080fd5b5061032e61063a366004614b60565b612388565b34801561064b57600080fd5b5061032e600e5481565b34801561066157600080fd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016102e0565b34801561069357600080fd5b5061032e6125e9565b3480156106a857600080fd5b506102d3612664565b3480156106bd57600080fd5b506007546001600160a01b031661066f565b3480156106db57600080fd5b5061032e6106ea366004614b60565b612673565b3480156106fb57600080fd5b5061030961070a366004614b36565b612842565b34801561071b57600080fd5b506103726128db565b34801561073057600080fd5b5061030961073f366004614b36565b6129a2565b34801561075057600080fd5b5061032e6129af565b34801561076557600080fd5b50610372610774366004614bb7565b612a40565b34801561078557600080fd5b5061032e610794366004614b60565b612bb8565b3480156107a557600080fd5b506103726107b4366004614b7b565b612d80565b3480156107c557600080fd5b506103726107d4366004614d89565b612d91565b3480156107e557600080fd5b5061032e6107f4366004614bb7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561082b57600080fd5b5061037261083a366004614b60565b612dc0565b34801561084b57600080fd5b5061037261085a366004614d89565b612e3f565b34801561086b57600080fd5b5060125461066f906001600160a01b031681565b61037261088d366004614bb7565b612efe565b34801561089e57600080fd5b506103726108ad366004614b60565b6130c4565b3480156108be57600080fd5b5061032e61315f565b3480156108d357600080fd5b506103726108e2366004614b36565b613178565b6060600380546108f690614ddd565b80601f016020809104026020016040519081016040528092919081815260200182805461092290614ddd565b801561096f5780601f106109445761010080835404028352916020019161096f565b820191906000526020600020905b81548152906001019060200180831161095257829003601f168201915b5050505050905090565b60006109863384846132f2565b5060015b92915050565b60008061099c60025490565b9050806109b257670de0b6b3a764000091505090565b60006109bc6129af565b90506000600e54826109ce9190614e2e565b90506000836109e583670de0b6b3a7640000614e46565b6109ef9190614e7b565b95945050505050565b610a006128db565b6001600160a01b0380821660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290610afc5760405162461bcd60e51b8152600401610af390614e8f565b60405180910390fd5b6012546101208201516040830151610b22926001600160a01b0391821692911690613416565b6101208101516001600160a01b03831660009081526014602052604081206007018054909190610b53908490614eae565b90915550506001600160a01b0382811660009081526014602090815260408083206008019290925561012084015160125483513381529283019190915290921682820152517f36119f4f28ae3384ed31589f21ec2992cb0ebe53b11c79a24466ee74471764ed9181900360600190a15050565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c0840152909190610cab5750600092915050565b600081606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d139190614ec5565b9050600082602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7d9190614ec5565b9050600083602001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de79190614ede565b90506000610e018386610100015187610120015185613479565b90506000610e14866020015185856134bd565b9050610e278282878960c001518761353d565b98975050505050505050565b60026006541415610e565760405162461bcd60e51b8152600401610af390614f01565b6002600655610e636128db565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290610f565760405162461bcd60e51b8152600401610af390614e8f565b6000610f628284613583565b604051632770a7eb60e21b8152336004820152602481018590529091506001600160a01b03851690639dc29fac90604401600060405180830381600087803b158015610fad57600080fd5b505af1158015610fc1573d6000803e3d6000fd5b505050508160000151156110ba5781604001516001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040161100191815260200190565b600060405180830381600087803b15801561101b57600080fd5b505af115801561102f573d6000803e3d6000fd5b50506040516000925033915083908381818185875af1925050503d8060008114611075576040519150601f19603f3d011682016040523d82523d6000602084013e61107a565b606091505b50509050806110b45760405162461bcd60e51b8152600401610af39060208082526004908201526310a2a92360e11b604082015260600190565b506110d3565b60408201516110d3906001600160a01b03163383613416565b6040518181526001600160a01b0385169033907f547518a7214f42d72dccc4ed54426ba50f889c24bb4d9766443e899a123381b39060200160405180910390a3505060016006555050565b6000600e546000141561113357506000919050565b600061113d61384b565b6001600160a01b03841660009081526013602052604081205491925090611165908390614e46565b9050670de0b6b3a7640000600061117c8284614f38565b1561118857600161118b565b60005b60ff166111988385614e7b565b6111a29190614e2e565b9695505050505050565b600260065414156111cf5760405162461bcd60e51b8152600401610af390614f01565b600260068181556001600160a01b0380841660009081526014602090815260409182902082516101e081018452815460ff811615158252610100908190048616938201939093526001820154851693810193909352948501548316606083015260038501549092166080820152600484015460a0820152600584015460c08201529183015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906112c75760405162461bcd60e51b8152600401610af390614e8f565b6112cf6128db565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611313573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113379190614ec5565b9050600082606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561137d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a19190614ec5565b9050600083604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140b9190614ede565b905060006114258486610100015187610120015185613479565b90506000611438866020015186856134bd565b9050600061144d8383878a60c0015188613892565b905060006114628484888b60c001518961353d565b905087610140015182108061147b575087610160015182115b6114af5760405162461bcd60e51b815260206004820152600560248201526410a62924a960d91b6044820152606401610af3565b6000670de0b6b3a76400006114c587600a615030565b6114cf8a85614e46565b6114d99190614e7b565b8a6101a001516114e99190614e46565b6114f39190614e7b565b905060008761150388600a615030565b61150d9084614e46565b6115179190614e7b565b9050896101400151841015611600576000670de0b6b3a7640000898c60a001516115419190614e46565b61154b9190614e7b565b611555908a614e2e565b9050600061156489600a615030565b61156e8385614e46565b6115789190614e7b565b90508b610180015181111561158f57506101808b01515b60006115bb8d60800151600760009054906101000a90046001600160a01b03168f6040015185886138e4565b90506115c78e82613993565b6020808e01516001600160a01b0316600090815260149091526040812060070180548692906115f7908490614e2e565b90915550505050505b896101600151841115611703576000670de0b6b3a7640000898c60a001516116289190614e46565b6116329190614e7b565b61163c908a614eae565b905060008161164c8a600a615030565b6116569086614e46565b6116609190614e7b565b90508b6101800151841115611698578161167b8a600a615030565b8d610180015161168b9190614e46565b6116959190614e7b565b90505b60808c015160408d01516007546000926116be9290916001600160a01b031685896138e4565b90506116ca8e86613a35565b6020808e01516001600160a01b0316600090815260149091526040812060070180548392906116fa908490614eae565b90915550505050505b60405184815233907fdf85796b4c3419ec22e630b81a8766863bb75964edc1c7869986126e66f633449060200160405180910390a250506001600655505050505050505050565b6000611757848484613b40565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156117dc5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610af3565b6117e985338584036132f2565b60019150505b9392505050565b6005546001600160a01b031633146118205760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906119135760405162461bcd60e51b8152600401610af390614e8f565b6001600160a01b0383811660008181526014602052604080822060030180546001600160a01b0319169487169485179055517f28c4fd18fb488de9f00ed376c22a3a7d2bbadabfaec7ab26651c824676f6fd4b9190a3505050565b60008061197961315f565b905061198481613d0e565b91505090565b611a29604051806101e0016040528060001515815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b506001600160a01b0390811660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e083015260078301549082015260088201546101208201526009820154610140820152600a820154610160820152600b820154610180820152600c8201546101a0820152600d909101546101c082015290565b6005546001600160a01b03163314611b285760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b03808c1660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c08201529015611c325760405162461bcd60e51b815260206004820152600360248201526221414560e81b6044820152606401610af3565b604051806101e001604052808e151581526020018d6001600160a01b031681526020018c6001600160a01b031681526020018b6001600160a01b031681526020018a6001600160a01b0316815260200189815260200188815260200187815260200160008152602001600081526020018681526020018581526020018481526020018381526020016000815250601460008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060808201518160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a0820151816004015560c0820151816005015560e0820151816006015561010082015181600701556101208201518160080155610140820151816009015561016082015181600a015561018082015181600b01556101a082015181600c01556101c082015181600d0155905050336001600160a01b03167f2a2b0348f99631bd5cb9665e0b2341476d6e9725bc1cc07c04f3c78fa958ad1f8d604051611e6e91906001600160a01b0391909116815260200190565b60405180910390a250505050505050505050505050565b6007546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015611ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef39190614ede565b905090565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610986918590611f2f908690614e2e565b6132f2565b60026006541415611f575760405162461bcd60e51b8152600401610af390614f01565b6002600655611f646128db565b60115415611fc55760115481600e54611f7b6129af565b611f859190614e2e565b611f8f9190614e2e565b10611fc55760405162461bcd60e51b8152600401610af39060208082526004908201526310a6a1a960e11b604082015260600190565b6000611fcf610990565b9050600081611fe684670de0b6b3a7640000614e46565b611ff09190614e7b565b60075490915061200b906001600160a01b0316333086613e70565b6120153382613ea8565b604080518481526020810184905290810182905233907f85a85f897cc05e4f2226d4f0a00a86d8c091e7b9af9155d98f54cf9bdcb96934906060015b60405180910390a25050600160065550565b61206f82333384613f87565b5050565b6005546001600160a01b0316331461209d5760405162461bcd60e51b8152600401610af39061503f565b60088590556009849055600a839055600b829055600c8190556040805186815260208101869052908101849052606081018390526080810182905233907f307727c989f3c87a872f36c0c665dec093dfee07d03e13be7d3d624637f436819060a00160405180910390a25050505050565b6121166128db565b600f54601254600754612136916001600160a01b03918216911683613416565b6000600f5560125460408051338152602081018490526001600160a01b03909216908201527f36119f4f28ae3384ed31589f21ec2992cb0ebe53b11c79a24466ee74471764ed906060015b60405180910390a150565b6001600160a01b0380821660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c08201529061227f5760405162461bcd60e51b8152600401610af390614e8f565b80516122b55760405162461bcd60e51b81526020600482015260056024820152642154524e4560d81b6044820152606401610af3565b600034116122ee5760405162461bcd60e51b8152600401610af39060208082526004908201526310a2a4ad60e11b604082015260600190565b80604001516001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561232d57600080fd5b505af1158015612341573d6000803e3d6000fd5b505050505061206f82303334613f87565b6005546001600160a01b0316331461237c5760405162461bcd60e51b8152600401610af39061503f565b6123866000614451565b565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c084015290919061246d5750600092915050565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d59190614ec5565b9050600082604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561251b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253f9190614ede565b905060006125598385610100015186610120015185613479565b9050600061256c856020015185856134bd565b9050600085606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d69190614ec5565b9050610e278383838960c0015188613892565b6000806125f461315f565b9050600061260182613d0e565b90506000600c54670de0b6b3a764000061261b9190614eae565b90506000670de0b6b3a76400006126328385614e46565b61263c9190614e7b565b9050670de0b6b3a76400006126518286614e46565b61265b9190614e7b565b94505050505090565b6060600480546108f690614ddd565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c08401529091906127585750600092915050565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561279c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c09190614ec5565b9050600082602001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612806573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061282a9190614ede565b90506109ef8284610100015185610120015184613479565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156128c45760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610af3565b6128d133858584036132f2565b5060019392505050565b600d544290808214156128ec575050565b600e54600f5460006128fc61196e565b9050600061290a8587614eae565b9050600061291b600e5484846144a3565b905061292781886144e6565b600e54600f5460408051898152602081018b9052908101889052606081018790526080810186905260a0810185905260c0810184905260e08101929092526101008201527f6359a1d821ddb244007da3e8ee241ce7b45d540a1896549f82566c50c68d7c60906101200160405180910390a150505050505050565b6000610986338484613b40565b6007546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156129fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a209190614ec5565b905080600f5410612a3357600091505090565b600f546119849082614eae565b6005546001600160a01b03163314612a6a5760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290612b5d5760405162461bcd60e51b8152600401610af390614e8f565b6001600160a01b0383811660008181526014602052604080822060020180546001600160a01b0319169487169485179055517fbf7ec739eb17989ec37b8022950e7d1780f24bd2f029fe363f8320b6b6042f7c9190a3505050565b6001600160a01b03808216600090815260146020908152604080832081516101e081018352815460ff81161515825261010090819004871694820194909452600182015486169281019290925260028101548516606083015260038101549094166080820152600484015460a0820152600584015460c0820152600684015460e0820181905260078501549282019290925260088401546101208201526009840154610140820152600a840154610160820152600b840154610180820152600c8401546101a0820152600d909301546101c0840152909190612c9d5750600092915050565b600081602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d059190614ec5565b9050600082602001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6f9190614ede565b90506109ef836020015183836134bd565b612d8c83338484613f87565b505050565b6005546001600160a01b03163314612dbb5760405162461bcd60e51b8152600401610af39061503f565b601155565b6005546001600160a01b03163314612dea5760405162461bcd60e51b8152600401610af39061503f565b601280546001600160a01b0319166001600160a01b0383169081179091556040805133815260208101929092527faaebcf1bfa00580e41d966056b48521fa9f202645c86d4ddf28113e617c1b1d39101612181565b60026006541415612e625760405162461bcd60e51b8152600401610af390614f01565b6002600655612e6f6128db565b6000612e79610990565b90506000670de0b6b3a7640000612e908484614e46565b612e9a9190614e7b565b600754909150612eb4906001600160a01b03163383613416565b612ebe3384614542565b604080518481526020810184905290810182905233907fc30dcbcc543321ea79e9955ec689be197278979aa6117ad1b66bebf48d0f204090606001612051565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c082015290612ff15760405162461bcd60e51b8152600401610af390614e8f565b80516130275760405162461bcd60e51b81526020600482015260056024820152642154524e4560d81b6044820152606401610af3565b600034116130605760405162461bcd60e51b8152600401610af39060208082526004908201526310a2a4ad60e11b604082015260600190565b80604001516001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561309f57600080fd5b505af11580156130b3573d6000803e3d6000fd5b5050505050612d8c83308434613f87565b6005546001600160a01b031633146130ee5760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0381166131535760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610af3565b61315c81614451565b50565b60008061316a6129af565b905061198481600e54614690565b6005546001600160a01b031633146131a25760405162461bcd60e51b8152600401610af39061503f565b6001600160a01b0380831660009081526014602090815260409182902082516101e081018452815460ff81161515825261010090819004861693820193909352600182015485169381019390935260028101548416606084015260038101549093166080830152600483015460a0830152600583015460c0830152600683015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906132955760405162461bcd60e51b8152600401610af390614e8f565b6001600160a01b03831660008181526014602052604090819020600d01849055517f5084e158024653e5c1fb3043afcfdfb3265f039c5bb0a81eace8ad704445002d906132e59085815260200190565b60405180910390a2505050565b6001600160a01b0383166133545760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610af3565b6001600160a01b0382166133b55760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610af3565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6040516001600160a01b038316602482015260448101829052612d8c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526146e9565b600084613488575060006134b5565b8461349483600a615030565b61349e8587614eae565b6134a89190614e46565b6134b29190614e7b565b90505b949350505050565b6000826134cc575060006117ef565b60006134d78561111e565b9050806134e85760009150506117ef565b60006134f584600a615030565b6134ff9083614e46565b90508461350c8183614f38565b1561351857600161351b565b60005b60ff166135288284614e7b565b6135329190614e2e565b979650505050505050565b600085158061354a575084155b156135565750816109ef565b600061356383600a615030565b61356d8689614e46565b6135779190614e7b565b90506135328682614eae565b60008083602001516001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ec9190614ec5565b9050600084604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613632573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136569190614ede565b9050600085606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561369c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136c09190614ec5565b905060006136da8488610100015189610120015186613479565b905060006136ed886020015186866134bd565b905060006136fc85600a615030565b6137068984614e46565b6137109190614e7b565b9050613720896020015182613a35565b600061372d86600a615030565b613737858b614e46565b6137419190614e7b565b90506000670de0b6b3a7640000868c60a0015161375e9190614e46565b6137689190614e7b565b6137729087614eae565b9050600061378188600a615030565b8361378d8a600a615030565b6137978587614e46565b6137a19190614e7b565b6137ac8b600a615030565b6137b69088614e46565b6137c09190614e7b565b6137ca9190614e46565b6137d49190614e7b565b60808d015160408e01516007549293506000926137fd9291906001600160a01b031685896138e4565b9050600061381861380e8387614eae565b8f60e001516147bb565b809250819d50505061383a8e6020015182876138349190614eae565b836147f0565b505050505050505050505092915050565b6000600e546000148061385e5750601054155b156138705750670de0b6b3a764000090565b601054600e5461388890670de0b6b3a7640000614e46565b611ef39190614e7b565b6000806138a083600a615030565b6138aa8689614e46565b6138b49190614e7b565b905060006138c5888888888861353d565b9050806138da83670de0b6b3a7640000614e46565b610e279190614e7b565b60006138fa6001600160a01b0386168785614855565b604051637f0148ab60e11b81526001600160a01b0386811660048301528581166024830152604482018590526064820184905287169063fe029156906084016020604051808303816000875af1158015613958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061397c9190614ec5565b90506109ef6001600160a01b038616876000614855565b600061399d61384b565b905081600e60008282546139b19190614e2e565b9091555060009050816139cc84670de0b6b3a7640000614e46565b6139d69190614e7b565b905080601060008282546139ea9190614e2e565b90915550506001600160a01b038416600090815260136020526040902054613a13908290614e2e565b6001600160a01b03909416600090815260136020526040902093909355505050565b6000613a3f61384b565b9050600e54821115613a55576000600e55613a6d565b81600e6000828254613a679190614eae565b90915550505b600081613a8284670de0b6b3a7640000614e46565b613a8c9190614e7b565b9050601054811115613aa2576000601055613aba565b8060106000828254613ab49190614eae565b90915550505b6001600160a01b038416600090815260136020526040902054811115613b0c576001600160a01b038416600090815260136020526040812080548290613b01908290614eae565b90915550613b3a9050565b6001600160a01b03841660009081526013602052604081208054839290613b34908490614eae565b90915550505b50505050565b6001600160a01b038316613ba45760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610af3565b6001600160a01b038216613c065760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610af3565b6001600160a01b03831660009081526020819052604090205481811015613c7e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610af3565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290613cb5908490614e2e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613d0191815260200190565b60405180910390a3613b3a565b6000670de0b6b3a76400008210613d27575050600b5490565b6008548211613da557600854600090613d4884670de0b6b3a7640000614e46565b613d529190614e7b565b90506000670de0b6b3a764000060095483613d6d9190614e46565b613d779190614e7b565b905060006109ef7f0000000000000000000000000000000000000000000000000000000001e1338083614e7b565b600060085483613db59190614eae565b90506000613dcb84670de0b6b3a7640000614eae565b9050600081613de284670de0b6b3a7640000614e46565b613dec9190614e7b565b90506000670de0b6b3a7640000600a5483613e079190614e46565b613e119190614e7b565b9050600081600954613e239190614e2e565b90506000613e517f0000000000000000000000000000000000000000000000000000000001e1338083614e7b565b9050600b548110613532575050600b549695505050505050565b919050565b6040516001600160a01b0380851660248301528316604482015260648101829052613b3a9085906323b872dd60e01b90608401613442565b6001600160a01b038216613efe5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610af3565b8060026000828254613f109190614e2e565b90915550506001600160a01b03821660009081526020819052604081208054839290613f3d908490614e2e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60026006541415613faa5760405162461bcd60e51b8152600401610af390614f01565b600260068181556001600160a01b0380871660009081526014602090815260409182902082516101e081018452815460ff811615158252610100908190048616938201939093526001820154851693810193909352948501548316606083015260038501549092166080820152600484015460a0820152600584015460c08201529183015460e0830181905260078401549183019190915260088301546101208301526009830154610140830152600a830154610160830152600b830154610180830152600c8301546101a0830152600d909201546101c0820152906140a25760405162461bcd60e51b8152600401610af390614e8f565b6101c081015115614104576101c08101516140be836002614e46565b8261010001516140ce9190614e2e565b106141045760405162461bcd60e51b8152600401610af39060208082526004908201526310a1a4a960e11b604082015260600190565b61410c6128db565b600061411786610bc6565b90506001600160a01b0385163014614143576040820151614143906001600160a01b0316863086613e70565b600080614154858560e001516147bb565b909250905080614165836002614e46565b61416f9190614e2e565b6020808601516001600160a01b03166000908152601490915260408120600701805490919061419f908490614e2e565b90915550506020808501516001600160a01b0316600090815260149091526040812060080180548392906141d4908490614e2e565b92505081905550600084606001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561421f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142439190614ec5565b9050600085604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614289573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142ad9190614ede565b90506000670de0b6b3a7640000838860a001516142ca9190614e46565b6142d49190614e7b565b6142de9084614e2e565b905060006142ed83600a615030565b6142f78388614e46565b6143019190614e7b565b90508061430c6129af565b116143425760405162461bcd60e51b8152600401610af390602080825260049082015263214e455360e01b604082015260600190565b600061436e8960800151600760009054906101000a90046001600160a01b03168b60400151858b6138e4565b905061437a8d82613993565b6000614389898988858961496a565b6040516340c10f1960e01b81526001600160a01b038e8116600483015260248201839052919250908f16906340c10f1990604401600060405180830381600087803b1580156143d757600080fd5b505af11580156143eb573d6000803e3d6000fd5b505050508d6001600160a01b03168c6001600160a01b03167fede1f310f6f94790fc59194108fa63c31d34618eb55c66f142a8eb2088770c4c8360405161443491815260200190565b60405180910390a350506001600655505050505050505050505050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008315806144b0575082155b806144b9575081155b156144c6575060006117ef565b6000670de0b6b3a7640000856144dc8587614e46565b6109e59190614e46565b6000670de0b6b3a764000083600c546144ff9190614e46565b6145099190614e7b565b905082600e600082825461451d9190614e2e565b9250508190555080600f60008282546145369190614e2e565b909155505050600d5550565b6001600160a01b0382166145a25760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610af3565b6001600160a01b038216600090815260208190526040902054818110156146165760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610af3565b6001600160a01b0383166000908152602081905260408120838303905560028054849290614645908490614eae565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60008161469f5750600061098a565b821580156146ad5750600082115b156146c15750670de0b6b3a764000061098a565b60006146cd8484614e2e565b6146df84670de0b6b3a7640000614e46565b6134b59190614e7b565b600061473e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166149c59092919063ffffffff16565b805190915015612d8c578080602001905181019061475c9190615074565b612d8c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610af3565b600080670de0b6b3a76400006147d18486614e46565b6147db9190614e7b565b90506147e78185614eae565b91509250929050565b6001600160a01b0383166000908152601460205260408120600701805484929061481b908490614eae565b90915550506001600160a01b0383166000908152601460205260408120600801805483929061484b908490614e2e565b9091555050505050565b8015806148cf5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156148a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148cd9190614ec5565b155b61493a5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610af3565b6040516001600160a01b038316602482015260448101829052612d8c90849063095ea7b360e01b90606401613442565b6000808361497984600a615030565b86614985896002614e46565b61498f9190614e46565b6149999190614e7b565b6149a39190614eae565b9050866149b184600a615030565b6149bb9083614e46565b6135329190614e7b565b60606134b5848460008585843b614a1e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610af3565b600080866001600160a01b03168587604051614a3a9190615091565b60006040518083038185875af1925050503d8060008114614a77576040519150601f19603f3d011682016040523d82523d6000602084013e614a7c565b606091505b509150915061353282828660608315614a965750816117ef565b825115614aa65782518084602001fd5b8160405162461bcd60e51b8152600401610af39190614aec565b60005b83811015614adb578181015183820152602001614ac3565b83811115613b3a5750506000910152565b6020815260008251806020840152614b0b816040850160208701614ac0565b601f01601f19169190910160400192915050565b80356001600160a01b0381168114613e6b57600080fd5b60008060408385031215614b4957600080fd5b614b5283614b1f565b946020939093013593505050565b600060208284031215614b7257600080fd5b6117ef82614b1f565b600080600060608486031215614b9057600080fd5b614b9984614b1f565b9250614ba760208501614b1f565b9150604084013590509250925092565b60008060408385031215614bca57600080fd5b614bd383614b1f565b9150614be160208401614b1f565b90509250929050565b8151151581526101e081016020830151614c0f60208401826001600160a01b03169052565b506040830151614c2a60408401826001600160a01b03169052565b506060830151614c4560608401826001600160a01b03169052565b506080830151614c6060808401826001600160a01b03169052565b5060a0838101519083015260c0808401519083015260e08084015190830152610100808401519083015261012080840151908301526101408084015190830152610160808401519083015261018080840151908301526101a080840151908301526101c092830151929091019190915290565b801515811461315c57600080fd5b6000806000806000806000806000806000806101808d8f031215614d0457600080fd5b8c35614d0f81614cd3565b9b50614d1d60208e01614b1f565b9a50614d2b60408e01614b1f565b9950614d3960608e01614b1f565b9850614d4760808e01614b1f565b9b9e9a9d50989b979a9960a0890135995060c08901359860e0810135985061010081013597506101208101359650610140810135955061016001359350915050565b600060208284031215614d9b57600080fd5b5035919050565b600080600080600060a08688031215614dba57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600181811c90821680614df157607f821691505b60208210811415614e1257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115614e4157614e41614e18565b500190565b6000816000190483118215151615614e6057614e60614e18565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614e8a57614e8a614e65565b500490565b6020808252600590820152642152544e4560d81b604082015260600190565b600082821015614ec057614ec0614e18565b500390565b600060208284031215614ed757600080fd5b5051919050565b600060208284031215614ef057600080fd5b815160ff811681146117ef57600080fd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082614f4757614f47614e65565b500690565b600181815b80851115614f87578160001904821115614f6d57614f6d614e18565b80851615614f7a57918102915b93841c9390800290614f51565b509250929050565b600082614f9e5750600161098a565b81614fab5750600061098a565b8160018114614fc15760028114614fcb57614fe7565b600191505061098a565b60ff841115614fdc57614fdc614e18565b50506001821b61098a565b5060208310610133831016604e8410600b841016171561500a575081810a61098a565b6150148383614f4c565b806000190482111561502857615028614e18565b029392505050565b60006117ef60ff841683614f8f565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561508657600080fd5b81516117ef81614cd3565b600082516150a3818460208701614ac0565b919091019291505056fea264697066735822122087643f065a980a4a954bc2572705531040ff2c5f36f37db464c1f0ea5bd01b6764736f6c634300080b0033

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

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc800000000000000000000000056b4a9675c52144c99f676835e83d5625cb47202000000000000000000000000000000000000000000000000000000000000001552697365646c65205661756c742045544855534443000000000000000000000000000000000000000000000000000000000000000000000000000000000000097276455448555344430000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): Risedle Vault ETHUSDC
Arg [1] : symbol (string): rvETHUSDC
Arg [2] : underlying (address): 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8
Arg [3] : feeRecipient (address): 0x56b4a9675c52144C99F676835e83d5625CB47202

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc8
Arg [3] : 00000000000000000000000056b4a9675c52144c99f676835e83d5625cb47202
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [5] : 52697365646c65205661756c7420455448555344430000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [7] : 7276455448555344430000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.