Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,651 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Public Mint | 11428952 | 24 mins ago | IN | 0 S | 0.04556629 | ||||
Public Mint | 11424829 | 50 mins ago | IN | 0 S | 0.09945075 | ||||
Public Mint | 11424356 | 53 mins ago | IN | 0 S | 0.07672803 | ||||
Public Mint | 11421050 | 1 hr ago | IN | 0 S | 0.0890387 | ||||
Public Mint | 11419301 | 1 hr ago | IN | 0 S | 0.07822563 | ||||
Public Mint | 11416800 | 1 hr ago | IN | 0 S | 0.04713297 | ||||
Public Mint | 11414430 | 1 hr ago | IN | 0 S | 0.04436245 | ||||
Public Mint | 11409012 | 2 hrs ago | IN | 0 S | 0.04676312 | ||||
Public Mint | 11400289 | 3 hrs ago | IN | 0 S | 0.04464295 | ||||
Public Mint | 11394868 | 3 hrs ago | IN | 0 S | 0.09894675 | ||||
Public Mint | 11394146 | 4 hrs ago | IN | 0 S | 0.05527974 | ||||
Public Mint | 11392223 | 4 hrs ago | IN | 0 S | 0.11753175 | ||||
Public Mint | 11388910 | 4 hrs ago | IN | 0 S | 0.09995475 | ||||
Public Mint | 11386939 | 4 hrs ago | IN | 0 S | 0.0480015 | ||||
Public Mint | 11385968 | 4 hrs ago | IN | 0 S | 0.04256631 | ||||
Public Mint | 11385891 | 4 hrs ago | IN | 0 S | 0.04632266 | ||||
Public Mint | 11385573 | 4 hrs ago | IN | 0 S | 0.0475975 | ||||
Public Mint | 11385170 | 4 hrs ago | IN | 0 S | 0.04309497 | ||||
Public Mint | 11384146 | 5 hrs ago | IN | 0 S | 0.04189113 | ||||
Public Mint | 11384113 | 5 hrs ago | IN | 0 S | 0.04309431 | ||||
Public Mint | 11384104 | 5 hrs ago | IN | 0 S | 0.04309497 | ||||
Public Mint | 11384078 | 5 hrs ago | IN | 0 S | 0.04515473 | ||||
Public Mint | 11384059 | 5 hrs ago | IN | 0 S | 0.04189113 | ||||
Public Mint | 11384037 | 5 hrs ago | IN | 0 S | 0.04309497 | ||||
Public Mint | 11383914 | 5 hrs ago | IN | 0 S | 0.04189113 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Minter
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {Ownable} from "./abstract/Ownable.sol"; import {ReentrancyGuard} from "./abstract/ReentrancyGuard.sol"; import {IBaseContracts} from "./interface/IBaseContracts.sol"; import {IERC20Custom} from "./interface/IERC20Custom.sol"; import {IERC20Token} from "./interface/IERC20Token.sol"; import {IERC20TokenRebase} from "./interface/IERC20TokenRebase.sol"; import {IFloor} from "./interface/IFloor.sol"; import {IMiscHelper} from "./interface/IMiscHelper.sol"; import {IPSM} from "./interface/IPSM.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC20 as IERC20Safe} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @title Minter * @dev Token minting controller with phased distribution * @notice Manages token issuance through whitelist and public phases */ contract Minter is Ownable, ReentrancyGuard { /// @notice Protocol helper contract /// @dev Facilitates cross-contract interactions IMiscHelper public helper; /// @notice Core protocol tokens IERC20Token public immutable dusx; IERC20TokenRebase public immutable sttx; IFloor public immutable floor; /// @notice Stablecoins and PSMs IERC20Custom[] public stables; IPSM[] public pegStabilityModules; /// @notice Treasury configuration address public immutable treasury; uint256 public immutable maxMintAmount; uint256 public constant TREASURY_ALLOCATION = 10; /// @notice Minting rates and state uint256 private constant RATES_LENGTH = 10; uint256[RATES_LENGTH] public rates; uint256 public currentRatio; uint256 public supplyMinted; bool public whitelistMintActive; bool public publicMintActive; mapping(address => bool) public whitelistedWallets; /// @notice Events event WhitelistMintEnabled(); event PublicMintEnabled(); event WalletWhitelisted(address indexed wallet); event TokensMinted(address indexed user, uint256 amount); /// @notice Custom errors error ApproveFailed(); error EmptyArray(); error InvalidMintAmount(); error MintAlreadyActive(); error MintNotActive(); error TokenReserveIsNotLowEnough(); error UnsupportedStablecoin(); error WalletNotWhitelisted(); error ZeroAddress(); error MintAmountCalculationFailed(uint256 stableAmount, uint256 rate); error MaxStableRangeCalculationFailed(uint256 supply, uint256 rate); modifier onlyWhitelisted() { if (!whitelistedWallets[_msgSender()]) revert WalletNotWhitelisted(); _; } /** * @notice Initializes the minting contract * @param baseContracts_ Base contracts instance for protocol integration * @param treasury_ Treasury address for fee collection */ constructor(IBaseContracts baseContracts_, address treasury_) { _ensureNonzeroAddress(address(baseContracts_)); _ensureNonzeroAddress(treasury_); // Get immutable contracts from BaseContracts helper = baseContracts_.helper(); dusx = baseContracts_.dusx(); sttx = baseContracts_.sttx(); floor = baseContracts_.floor(); _ensureNonzeroAddress(address(helper)); _ensureNonzeroAddress(address(dusx)); _ensureNonzeroAddress(address(sttx)); _ensureNonzeroAddress(address(floor)); // Initialize PSMs and get their stablecoins IPSM[] memory psms_ = new IPSM[](2); psms_[0] = baseContracts_.psmCircle(); psms_[1] = baseContracts_.psmTether(); if (address(psms_[0]) == address(0) || address(psms_[1]) == address(0)) revert ZeroAddress(); pegStabilityModules = psms_; // Get stablecoins from PSMs IERC20Custom[] memory stables_ = new IERC20Custom[](2); stables_[0] = psms_[0].stableToken(); // Circle PSM -> USDC stables_[1] = psms_[1].stableToken(); // Tether PSM -> USDT if ( address(stables_[0]) == address(0) || address(stables_[1]) == address(0) ) revert ZeroAddress(); stables = stables_; treasury = treasury_; rates = [4380, 4380, 4175, 4175, 4008, 4008, 4008, 4008, 4008, 4008]; maxMintAmount = ((73_146_000 * 25) / 10) * 10 ** sttx.decimals(); _setupApprovals(stables, pegStabilityModules); } /** * @notice Adds a wallet to whitelist * @param wallet Address to whitelist */ function addWallet(address wallet) external onlyOwner { whitelistedWallets[wallet] = true; emit WalletWhitelisted(wallet); } /** * @notice Adds multiple wallets to whitelist * @param wallets Array of addresses to whitelist */ function addWalletBatch(address[] memory wallets) external onlyOwner { uint256 length = wallets.length; for (uint256 i; i < length; i++) { whitelistedWallets[wallets[i]] = true; emit WalletWhitelisted(wallets[i]); } } /** * @notice Enables whitelist minting phase */ function enableWhitelistMint() external onlyOwner { if (whitelistMintActive) revert MintAlreadyActive(); whitelistMintActive = true; emit WhitelistMintEnabled(); } /** * @notice Enables public minting phase */ function enablePublicMint() external onlyOwner { if (publicMintActive) revert MintAlreadyActive(); publicMintActive = true; emit PublicMintEnabled(); } /** * @notice Mints tokens during whitelist phase * @param stablecoin Stablecoin used for minting * @param stableAmount Amount of stablecoin to mint against */ function whitelistMint( IERC20Custom stablecoin, uint256 stableAmount ) external nonReentrant onlyWhitelisted { if (!whitelistMintActive) revert MintNotActive(); _mint(stablecoin, stableAmount); } /** * @notice Mints tokens during public phase * @param stablecoin Stablecoin used for minting * @param stableAmount Amount of stablecoin to mint against */ function publicMint( IERC20Custom stablecoin, uint256 stableAmount ) external nonReentrant { if (!publicMintActive) revert MintNotActive(); _mint(stablecoin, stableAmount); } /** * @notice Mints remaining token supply * @param stablecoin Stablecoin used for minting */ function mintRemainingSupply( IERC20Custom stablecoin ) external nonReentrant { if (!publicMintActive) revert MintNotActive(); if (tokenReserve() >= sttx.maxSupply() / 100) revert TokenReserveIsNotLowEnough(); uint256 decimalsDifference = 10 ** (sttx.decimals() - stablecoin.decimals()); uint256 stableAmount = (tokenReserve() / (rates[rates.length - 1])) / decimalsDifference; _mint(stablecoin, stableAmount); } /** * @notice Sends accumulated DUSX to floor contract */ function sendToFloorDUSX() external nonReentrant { _sendToFloorDUSX(); } /** * @notice Verifies if a wallet is whitelisted * @param wallet Address to verify * @return bool Whitelist status */ function verifyWallet(address wallet) external view returns (bool) { return whitelistedWallets[wallet]; } /** * @notice Calculates mint amount for given stablecoin input * @param stablecoin Stablecoin used for calculation * @param stableAmount Amount of stablecoin * @return uint256 Calculated mint amount */ function calcMintAmount( IERC20Custom stablecoin, uint256 stableAmount ) public view returns (uint256) { uint256[RATES_LENGTH] memory supplyRangeLeft; uint256[RATES_LENGTH] memory maxStablePerRange = [ uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0) ]; bool maxStablePerRangeUpdated = false; uint256 mintAmount = 0; uint256 decimalsDifference = 10 ** (sttx.decimals() - stablecoin.decimals()); for (uint256 i; i < RATES_LENGTH; i++) { supplyRangeLeft[i] = (sttx.maxSupply() / RATES_LENGTH); // Check for overflow in maxStablePerRange calculation uint256 maxStable = ((sttx.maxSupply() / RATES_LENGTH) / rates[i]) / decimalsDifference; if (maxStable == 0 && (sttx.maxSupply() / RATES_LENGTH) != 0) { revert MaxStableRangeCalculationFailed( sttx.maxSupply() / RATES_LENGTH, rates[i] ); } maxStablePerRange[i] = maxStable; } for (uint256 i; i < RATES_LENGTH; i++) { if (currentRatio < ((i + 1) * 100) / RATES_LENGTH) { supplyRangeLeft[i] = (sttx.maxSupply() / RATES_LENGTH) * (i + 1) - supplyMinted; if (!maxStablePerRangeUpdated) { uint256 maxStable = (supplyRangeLeft[i] / rates[i]) / decimalsDifference; if (maxStable == 0 && supplyRangeLeft[i] != 0) { revert MaxStableRangeCalculationFailed( supplyRangeLeft[i], rates[i] ); } maxStablePerRange[i] = maxStable; maxStablePerRangeUpdated = true; } if (stableAmount <= maxStablePerRange[i]) { uint256 amount = (stableAmount * rates[i]) * decimalsDifference; if ( amount / rates[i] / decimalsDifference != stableAmount ) { revert MintAmountCalculationFailed( stableAmount, rates[i] ); } mintAmount += amount; break; } else { uint256 amount = (maxStablePerRange[i] * rates[i]) * decimalsDifference; if ( amount / rates[i] / decimalsDifference != maxStablePerRange[i] ) { revert MintAmountCalculationFailed( maxStablePerRange[i], rates[i] ); } mintAmount += amount; stableAmount -= maxStablePerRange[i]; } } else { maxStablePerRangeUpdated = false; } } return mintAmount > tokenReserve() ? tokenReserve() : mintAmount; } function calcStableAmount( IERC20Custom stablecoin, uint256 mintAmount ) public view returns (uint256) { uint256[RATES_LENGTH] memory maxStablePerRange = [ uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0) ]; bool maxStablePerRangeUpdated = false; uint256 stableAmount = 0; uint256 decimalsDifference = 10 ** (sttx.decimals() - stablecoin.decimals()); for (uint256 i; i < RATES_LENGTH; i++) { maxStablePerRange[i] = ((sttx.maxSupply() / RATES_LENGTH) / rates[i]) / decimalsDifference; } for (uint256 i; i < RATES_LENGTH; i++) { if (currentRatio < ((i + 1) * 100) / RATES_LENGTH) { if (!maxStablePerRangeUpdated) { maxStablePerRange[i] = (((sttx.maxSupply() / RATES_LENGTH) * (i + 1) - supplyMinted) / rates[i]) / decimalsDifference; maxStablePerRangeUpdated = true; } if ( mintAmount <= (maxStablePerRange[i] * rates[i]) * decimalsDifference ) { stableAmount += mintAmount / (rates[i] * decimalsDifference); break; } else { stableAmount += maxStablePerRange[i]; mintAmount -= (maxStablePerRange[i] * rates[i]) * decimalsDifference; } } else { maxStablePerRangeUpdated = false; } } return stableAmount; } function tokenReserve() public view returns (uint256) { return sttx.maxSupply() - supplyMinted; } function _mint(IERC20Custom stablecoin, uint256 stableAmount) private { if (!_checkStable(stablecoin)) revert UnsupportedStablecoin(); uint256 toMint = calcMintAmount(stablecoin, stableAmount); if (toMint == 0 || toMint > tokenReserve() || toMint > maxMintAmount) revert InvalidMintAmount(); uint256 floorAmount = (stableAmount * (100 - TREASURY_ALLOCATION)) / 100; supplyMinted += toMint; currentRatio = (supplyMinted * 100) / sttx.maxSupply(); SafeERC20.safeTransferFrom( IERC20Safe(address(stablecoin)), _msgSender(), address(this), stableAmount ); IERC20TokenRebase(address(sttx)).rebase(); IERC20TokenRebase(address(sttx)).mint(_msgSender(), toMint); uint256 length = stables.length; for (uint256 i; i < length; i++) { if (stablecoin == stables[i]) { helper.psmSwapStableForDUSX( pegStabilityModules[i], address(this), floorAmount ); break; } } SafeERC20.safeTransfer( IERC20Safe(address(stablecoin)), treasury, stablecoin.balanceOf(address(this)) ); _sendToFloorDUSX(); emit TokensMinted(_msgSender(), toMint); } function _sendToFloorDUSX() private { uint256 dusxBalance = dusx.balanceOf(address(this)); if (dusxBalance > 0) { helper.depositFloor(dusxBalance); } } function _setupApprovals( IERC20Custom[] memory stables_, IPSM[] memory psms_ ) private { uint256 length = stables_.length; for (uint256 i; i < length; i++) { bool successStables = stables_[i].approve( address(psms_[i]), type(uint256).max ); if (!successStables) { revert ApproveFailed(); } } bool successDUSX = dusx.approve(address(floor), type(uint256).max); if (!successDUSX) { revert ApproveFailed(); } } function _checkStable(IERC20Custom stablecoin) private view returns (bool) { uint256 length = stables.length; bool found = false; for (uint256 i; i < length; i++) { if (stablecoin == stables[i]) { found = true; break; } } return found; } // Validates that an address is not zero function _ensureNonzeroAddress(address addr) private pure { if (addr == address(0)) { revert ZeroAddress(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 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 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title Context * @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, as 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). * @notice This contract is used through inheritance. It will make available the * modifier `_msgSender()`, which can be used to reference the account that * called a function within an implementing contract. */ abstract contract Context { /*////////////////////////////////////////////////////////////// INTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Gets the sender of the current call * @dev Provides a way to retrieve the message sender that supports meta-transactions * @return Sender address (msg.sender in the base implementation) */ function _msgSender() internal view virtual returns (address) { return msg.sender; } /** * @notice Gets the complete calldata of the current call * @dev Provides a way to retrieve the message data that supports meta-transactions * @return Complete calldata bytes */ function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @notice Gets the length of any context-specific suffix in the message data * @dev Used in meta-transaction implementations to account for additional data * @return Length of the context suffix (0 in the base implementation) */ function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {Context} from "./Context.sol"; /** * @title Ownable * @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. * @notice By default, the owner account will be the one that deploys the contract. * This can later be changed with {transferOwnership} and {renounceOwnership}. */ abstract contract Ownable is Context { /*////////////////////////////////////////////////////////////// STATE VARIABLES //////////////////////////////////////////////////////////////*/ /// @notice Address of the current owner address private _owner; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ /// @notice Emitted when ownership is transferred event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /*////////////////////////////////////////////////////////////// CUSTOM ERRORS //////////////////////////////////////////////////////////////*/ /// @notice Thrown when non-owner tries to call owner-only function error UnauthorizedAccount(address account); /// @notice Thrown when trying to transfer ownership to invalid address error InvalidOwner(address owner); /*////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////*/ /** * @dev Throws if called by any account other than the owner */ modifier onlyOwner() { _checkOwner(); _; } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ /** * @dev Initializes the contract setting the deployer as the initial owner */ constructor() { _transferOwnership(_msgSender()); } /*////////////////////////////////////////////////////////////// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Leaves the contract without owner * @dev 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 { _transferOwnership(address(0)); } /** * @notice Transfers ownership of the contract to a new account * @dev The new owner cannot be the zero address * @param newOwner The address that will become the new owner */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert InvalidOwner(address(0)); } _transferOwnership(newOwner); } /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Returns the address of the current owner * @return Current owner address */ function owner() public view virtual returns (address) { return _owner; } /*////////////////////////////////////////////////////////////// INTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @dev Transfers ownership of the contract to a new account (`newOwner`) * Internal function without access restriction */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev Throws if the sender is not the owner */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert UnauthorizedAccount(_msgSender()); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title ReentrancyGuard * @dev Contract module that helps prevent reentrant calls to a function * @notice This module is used through inheritance. It will make available the modifier * `nonReentrant`, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. */ abstract contract ReentrancyGuard { /*////////////////////////////////////////////////////////////// STATE VARIABLES //////////////////////////////////////////////////////////////*/ /// @notice Guard state constants uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; /// @notice Current state of the guard uint256 private _status; /*////////////////////////////////////////////////////////////// CUSTOM ERRORS //////////////////////////////////////////////////////////////*/ error ReentrantCall(); /*////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////*/ /** * @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 making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ /** * @notice Initializes the contract by setting the initial reentrancy guard state */ constructor() { _status = NOT_ENTERED; } /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Checks if a protected function is currently executing * @return True if the contract is in the entered state */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } /*////////////////////////////////////////////////////////////// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @dev Sets guard state before protected function execution * @notice Reverts if a reentrant call is detected */ function _nonReentrantBefore() private { if (_status == ENTERED) { revert ReentrantCall(); } _status = ENTERED; } /** * @dev Resets guard state after protected function execution */ function _nonReentrantAfter() private { _status = NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IDUSXProvider} from "./IDUSXProvider.sol"; import {IERC20Token} from "./IERC20Token.sol"; import {IERC20TokenRebase} from "./IERC20TokenRebase.sol"; import {IFeesDistributor} from "./IFees.sol"; import {IFeesWithdrawer} from "./IFees.sol"; import {IFloor} from "./IFloor.sol"; import {ILenderOwner} from "./ILenderOwner.sol"; import {ILiquidationHelper} from "./ILiquidationHelper.sol"; import {IMarketLens} from "./IMarketLens.sol"; import {IMiscHelper} from "./IMiscHelper.sol"; import {IOracle} from "./IOracle.sol"; import {IPSM} from "./IPSM.sol"; import {IRepayHelper} from "./IRepayHelper.sol"; import {IStableOwner} from "./IStableOwner.sol"; import {IStakedDUSX} from "./IStakedDUSX.sol"; import {ISupplyHangingCalculator} from "./ISupplyHangingCalculator.sol"; import {IVault} from "./IVault.sol"; import {IVoteEscrowedSTTX} from "./IVoteEscrowedSTTX.sol"; import {IDynamicInterestRate} from "./IDynamicInterestRate.sol"; import {IMinter} from "./IMinter.sol"; interface IBaseContracts { struct CoreTokens { IERC20Token dusx; IERC20TokenRebase sttx; IStakedDUSX stDUSX; IVoteEscrowedSTTX veSTTX; } struct PSMContracts { IPSM psmCircle; IPSM psmTether; IStableOwner stableOwner; } struct OracleContracts { IOracle oracleChainlink; IOracle oracleFloorPrice; } struct HelperContracts { IMiscHelper helper; ILiquidationHelper liquidationHelper; IRepayHelper repayHelper; IMarketLens marketLens; } error ZeroAddress(); error ContractAlreadySet(); // Struct getters function coreTokens() external view returns (CoreTokens memory); function psmContracts() external view returns (PSMContracts memory); function oracleContracts() external view returns (OracleContracts memory); function helperContracts() external view returns (HelperContracts memory); // Individual contract getters function dusxProvider() external view returns (IDUSXProvider); function feesDistributor() external view returns (IFeesDistributor); function feesWithdrawer() external view returns (IFeesWithdrawer); function floor() external view returns (IFloor); function lenderOwner() external view returns (ILenderOwner); function minter() external view returns (IMinter); function supplyCalculator() external view returns (ISupplyHangingCalculator); function vault() external view returns (IVault); function dynamicInterestRate() external view returns (IDynamicInterestRate); // Convenience getters for struct members function dusx() external view returns (IERC20Token); function sttx() external view returns (IERC20TokenRebase); function stDUSX() external view returns (IStakedDUSX); function veSTTX() external view returns (IVoteEscrowedSTTX); function psmCircle() external view returns (IPSM); function psmTether() external view returns (IPSM); function stableOwner() external view returns (IStableOwner); function oracleChainlink() external view returns (IOracle); function oracleFloorPrice() external view returns (IOracle); function helper() external view returns (IMiscHelper); function liquidationHelper() external view returns (ILiquidationHelper); function repayHelper() external view returns (IRepayHelper); function marketLens() external view returns (IMarketLens); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IDUSXProvider * @dev Interface for DUSX token provision and distribution operations * @notice Defines functionality for: * 1. Token provision management * 2. Supply control * 3. Distribution tracking */ interface IDUSXProvider { /*////////////////////////////////////////////////////////////// PROVISION OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Provides DUSX tokens to the requesting address * @param amount The quantity of DUSX tokens to provide in base units * @dev Handles: * · Token minting/transfer * · Supply tracking * · State updates * * Requirements: * · Caller is authorized * · Amount > 0 * · Within supply limits * * Effects: * · Increases recipient balance * · Updates total supply * · Emits provision event */ function provide(uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IDynamicInterestRate * @dev Interface for dynamic interest rate calculations in the lending protocol * @notice Defines methods for retrieving time-based interest rates that: * 1. Adjust based on market conditions * 2. Support per-second and base rate calculations * 3. Maintain precision through proper scaling * * This interface is crucial for: * · Accurate interest accrual * · Dynamic market response * · Protocol yield calculations */ interface IDynamicInterestRate { /*////////////////////////////////////////////////////////////// INTEREST RATE QUERIES //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves the current interest rate per second * @return uint256 Interest rate per second, scaled by 1e18 * @dev Used for precise interest calculations over time periods */ function getInterestPerSecond() external view returns (uint256); /** * @notice Retrieves the current base interest rate * @return uint256 Base interest rate, scaled by 1e18 * @dev Represents the foundational rate before adjustments */ function getInterestRate() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IERC20Custom * @dev Interface for the ERC20 fungible token standard (EIP-20) * @notice Defines functionality for: * 1. Token transfers * 2. Allowance management * 3. Balance tracking * 4. Token metadata */ interface IERC20Custom { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ /** * @dev Emitted on token transfer between addresses * @param from Source address (0x0 for mints) * @param to Destination address (0x0 for burns) * @param value Amount of tokens transferred * @notice Tracks: * · Regular transfers * · Minting operations * · Burning operations */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when spending allowance is granted * @param owner Address granting permission * @param spender Address receiving permission * @param value Amount of tokens approved * @notice Records: * · New approvals * · Updated allowances * · Revoked permissions */ event Approval( address indexed owner, address indexed spender, uint256 value ); /*////////////////////////////////////////////////////////////// TRANSFER OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Transfers tokens to specified recipient * @param to Recipient address * @param value Amount to transfer in base units * @return bool True if transfer succeeds * @dev Requirements: * · Caller has sufficient balance * · Recipient is valid * · Amount > 0 * * Effects: * · Decreases caller balance * · Increases recipient balance * · Emits Transfer event */ function transfer(address to, uint256 value) external returns (bool); /** * @notice Executes transfer on behalf of token owner * @param from Source address * @param to Destination address * @param value Amount to transfer in base units * @return bool True if transfer succeeds * @dev Requirements: * · Caller has sufficient allowance * · Source has sufficient balance * · Valid addresses * * Effects: * · Decreases allowance * · Updates balances * · Emits Transfer event */ function transferFrom( address from, address to, uint256 value ) external returns (bool); /*////////////////////////////////////////////////////////////// APPROVAL OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Authorizes address to spend tokens * @param spender Address to authorize * @param value Amount to authorize in base units * @return bool True if approval succeeds * @dev Controls: * · Spending permissions * · Delegation limits * · Authorization levels * * Security: * · Overwrites previous allowance * · Requires explicit value * · Emits Approval event */ function approve(address spender, uint256 value) external returns (bool); /*////////////////////////////////////////////////////////////// TOKEN METADATA //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves human-readable token name * @return string Full token name */ function name() external view returns (string memory); /** * @notice Retrieves token trading symbol * @return string Short token identifier */ function symbol() external view returns (string memory); /** * @notice Retrieves token decimal precision * @return uint8 Number of decimal places * @dev Standard: * · 18 for most tokens * · Used for display formatting */ function decimals() external view returns (uint8); /*////////////////////////////////////////////////////////////// BALANCE QUERIES //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves total token supply * @return uint256 Current total supply * @dev Reflects: * · All minted tokens * · Minus burned tokens * · In base units */ function totalSupply() external view returns (uint256); /** * @notice Retrieves account token balance * @param account Address to query * @return uint256 Current balance in base units * @dev Returns: * · Available balance * · Includes pending rewards * · Excludes locked tokens */ function balanceOf(address account) external view returns (uint256); /** * @notice Retrieves remaining spending allowance * @param owner Token owner address * @param spender Authorized spender address * @return uint256 Current allowance in base units * @dev Shows: * · Approved amount * · Remaining limit * · Delegation status */ function allowance( address owner, address spender ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IERC20Custom} from "./IERC20Custom.sol"; /** * @title IERC20Token * @dev Extended interface for ERC20 tokens with supply control capabilities * @notice Defines functionality for: * 1. Token minting * 2. Token burning * 3. Supply management */ interface IERC20Token is IERC20Custom { /*////////////////////////////////////////////////////////////// SUPPLY MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * @notice Mints new tokens to specified account * @param account Address to receive minted tokens * @param amount Quantity of tokens to mint in base units * @dev Controls: * · Supply expansion * · Balance updates * · Event emission * * Requirements: * · Caller is authorized * · Within maxSupply * · Valid recipient */ function mint(address account, uint256 amount) external; /** * @notice Burns tokens from specified account * @param account Address to burn tokens from * @param amount Quantity of tokens to burn in base units * @dev Manages: * · Supply reduction * · Balance updates * · Event emission * * Requirements: * · Caller is authorized * · Sufficient balance * · Amount > 0 */ function burn(address account, uint256 amount) external; /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves maximum token supply limit * @return uint256 Maximum supply cap in base units * @dev Enforces: * · Supply ceiling * · Mint restrictions * · Protocol limits * * Note: This is an immutable value that * cannot be exceeded by minting operations */ function maxSupply() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IERC20Custom} from "./IERC20Custom.sol"; /** * @title IERC20TokenRebase * @dev Extended interface for ERC20 tokens with elastic supply and safe management * @notice Defines functionality for: * 1. Supply elasticity (rebasing) * 2. Safe-based token management * 3. Supply control mechanisms * 4. Configuration management */ interface IERC20TokenRebase is IERC20Custom { /*////////////////////////////////////////////////////////////// SUPPLY MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * @notice Mints new tokens to specified account * @param account Address to receive minted tokens * @param amount Quantity of tokens to mint in base units * @dev Requires: * · Caller is authorized minter * · Within maxSupply limits * · Valid recipient */ function mint(address account, uint256 amount) external; /** * @notice Burns tokens from specified account * @param account Address to burn tokens from * @param amount Quantity of tokens to burn in base units * @dev Requires: * · Caller is authorized * · Account has sufficient balance * · Amount > 0 */ function burn(address account, uint256 amount) external; /*////////////////////////////////////////////////////////////// REBASE OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Executes supply rebase based on current parameters * @dev Triggers: * · Supply adjustment * · Balance recalculation * · Event emission * * Considers: * · Rebase interval * · Basis points * · Supply limits */ function rebase() external; /** * @notice Configures rebase parameters * @param rebaseInterval Time period between rebases (in seconds) * @param rebaseBasisPoints Scale factor for rebase (in basis points) * @dev Controls: * · Rebase frequency * · Rebase magnitude * · Supply elasticity */ function setRebaseConfig( uint256 rebaseInterval, uint256 rebaseBasisPoints ) external; /*////////////////////////////////////////////////////////////// SAFE MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * @notice Initializes new token management safe * @param safe Address of safe to create * @dev Establishes: * · Safe permissions * · Access controls * · Management capabilities */ function createSafe(address safe) external; /** * @notice Removes existing token management safe * @param safe Address of safe to remove * @dev Handles: * · Permission revocation * · State cleanup * · Access termination */ function destroySafe(address safe) external; /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves floor contract address * @return address Active floor contract * @dev Used for: * · Price stability * · Supply control */ function floor() external view returns (address); /** * @notice Retrieves authorized minter address * @return address Active minter contract * @dev Controls: * · Mint permissions * · Supply expansion */ function minter() external view returns (address); /** * @notice Returns absolute maximum token supply * @return uint256 Maximum supply cap in base units * @dev Enforces: * · Hard supply limit * · Mint restrictions */ function maxSupply() external view returns (uint256); /** * @notice Calculates maximum supply after rebase * @return uint256 Post-rebase maximum supply in base units * @dev Considers: * · Current max supply * · Rebase parameters * · Supply caps */ function maxSupplyRebased() external view returns (uint256); /** * @notice Calculates total supply after rebase * @return uint256 Post-rebase total supply in base units * @dev Reflects: * · Current supply * · Rebase effects * · Supply limits */ function totalSupplyRebased() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IFeesWithdrawer * @dev Interface for protocol fee withdrawal operations * @notice Defines functionality for: * 1. Secure fee withdrawal * 2. Access control for withdrawals * 3. Protocol revenue management * * This interface ensures: * · Controlled access to protocol fees * · Safe transfer of accumulated revenue * · Proper accounting of withdrawn amounts */ interface IFeesWithdrawer { /*////////////////////////////////////////////////////////////// WITHDRAWAL OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Withdraws accumulated protocol fees to designated recipients * @dev Only callable by authorized withdrawers * Handles: * · Fee accounting updates * · Transfer of tokens * · Event emission for tracking */ function withdraw() external; } /** * @title IFeesDistributor * @dev Interface for protocol fee distribution and allocation * @notice Defines functionality for: * 1. Fee distribution across protocol components * 2. Dynamic allocation management * 3. Floor token revenue sharing * * This interface manages: * · Revenue distribution logic * · Allocation percentages * · Protocol incentive mechanisms */ interface IFeesDistributor { /*////////////////////////////////////////////////////////////// DISTRIBUTION OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Distributes accumulated protocol fees according to set allocations * @dev Handles the distribution of fees to: * · Floor token stakers * · Protocol treasury * · Other designated recipients */ function distribute() external; /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Returns current percentage allocated to Floor token stakers * @return uint256 Floor allocation percentage, scaled by 1e18 */ function floorAllocation() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IFloor * @dev Interface for protocol floor price management and capital operations * @notice Defines functionality for: * 1. Token deposit management * 2. Refund processing * 3. Capital tracking */ interface IFloor { /*////////////////////////////////////////////////////////////// DEPOSIT OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Processes token deposits into the floor contract * @param msgSender Address initiating the deposit * @param amount Quantity of tokens to deposit * @dev Handles: * · Token transfer validation * · Capital tracking updates * · Event emission */ function deposit(address msgSender, uint256 amount) external; /*////////////////////////////////////////////////////////////// REFUND OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Processes token refunds from the floor contract * @param msgSender Address receiving the refund * @param amount Quantity of tokens to refund * @dev Ensures: * · Sufficient contract balance * · Authorized withdrawal * · Capital accounting */ function refund(address msgSender, uint256 amount) external; /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Returns current total capital held in the floor contract * @return uint256 Current capital amount in base units * @dev Used for: * · Floor price calculations * · Protocol health metrics * · Capital adequacy checks */ function capital() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {Rebase} from "../library/AuxRebase.sol"; import {IERC20Custom} from "./IERC20Custom.sol"; import {IOracle} from "./IOracle.sol"; import {IVault} from "./IVault.sol"; /** * @title ILender * @dev Interface for lending operations and management * @notice Defines the core lending protocol functionality including: * 1. Collateral management and borrowing operations * 2. Interest rate and fee management * 3. Liquidation handling * 4. Vault integration * * The interface is designed to support: * · Over-collateralized lending * · Dynamic interest rates * · Liquidation mechanisms * · Fee collection and distribution */ interface ILender { /*////////////////////////////////////////////////////////////// ADMIN CONFIGURATION //////////////////////////////////////////////////////////////*/ /** * @notice Updates the interest rate for borrowing * @param newInterestRate New interest rate (scaled by 1e18) */ function changeInterestRate(uint256 newInterestRate) external; /** * @notice Sets global and per-address borrowing limits * @param newBorrowLimit Total borrowing limit for the protocol * @param perAddressPart Maximum borrow amount per address */ function changeBorrowLimit( uint256 newBorrowLimit, uint256 perAddressPart ) external; /*////////////////////////////////////////////////////////////// CORE LENDING OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Updates protocol state with accrued interest */ function accrue() external; /** * @notice Updates the exchange rate from the oracle */ function updateExchangeRate() external; /** * @notice Withdraws accumulated protocol fees * @param amountToProvide Amount of fees to withdraw */ function withdrawFees(uint256 amountToProvide) external; /*////////////////////////////////////////////////////////////// LIQUIDATION HANDLING //////////////////////////////////////////////////////////////*/ /** * @notice Liquidates undercollateralized positions * @param liquidator Address performing the liquidation * @param users Array of user addresses to liquidate * @param maxBorrowParts Maximum borrow parts to liquidate per user * @param to Address to receive liquidated collateral */ function liquidate( address liquidator, address[] memory users, uint256[] memory maxBorrowParts, address to ) external; /*////////////////////////////////////////////////////////////// VAULT OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Deposits collateral into the vault * @param amount Amount of collateral to deposit */ function vaultDepositAddCollateral(uint256 amount) external; /** * @notice Withdraws borrowed assets from the vault * @param msgSender Address initiating the withdrawal * @param amount Amount to withdraw * @return part Borrow part assigned * @return share Share of the vault */ function borrowVaultWithdraw( address msgSender, uint256 amount ) external returns (uint256 part, uint256 share); /*////////////////////////////////////////////////////////////// COLLATERAL MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * @notice Adds collateral to a lending position * @param to Address to credit the collateral * @param skim True to skim tokens from the contract * @param share Amount of shares to add as collateral */ function addCollateral(address to, bool skim, uint256 share) external; /** * @notice Removes collateral from a lending position * @param to Address to receive the removed collateral * @param share Amount of shares to remove */ function removeCollateral(address to, uint256 share) external; /*////////////////////////////////////////////////////////////// BORROWING OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Borrows assets against deposited collateral * @param msgSender Address initiating the borrow * @param amount Amount to borrow * @return part Borrow part assigned * @return share Share of the borrowed amount */ function borrow( address msgSender, uint256 amount ) external returns (uint256 part, uint256 share); /** * @notice Repays borrowed assets * @param payer Address paying the debt * @param to Address whose debt to repay * @param skim True to skim tokens from the contract * @param part Amount of borrow part to repay * @return amount Actual amount repaid */ function repay( address payer, address to, bool skim, uint256 part ) external returns (uint256 amount); /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Gets the oracle contract address * @return IOracle Oracle interface */ function oracle() external view returns (IOracle); /** * @notice Gets interest accrual information * @return Last accrual timestamp, accumulated interest, interest per second */ function accrueInfo() external view returns (uint256, uint256, uint256); /** * @notice Gets the required collateral ratio * @return uint256 Collateral ratio (scaled by 1e5) */ function collateralRatio() external view returns (uint256); /** * @notice Gets the liquidation bonus multiplier * @return uint256 Liquidation multiplier (scaled by 1e5) */ function liquidationMultiplier() external view returns (uint256); /** * @notice Gets total collateral shares in the protocol * @return uint256 Total collateral share amount */ function totalCollateralShare() external view returns (uint256); /** * @notice Gets the vault contract address * @return IVault Vault interface */ function vault() external view returns (IVault); /** * @notice Gets the fee recipient address * @return address Fee recipient */ function feeTo() external view returns (address); /** * @notice Gets the collateral token address * @return IERC20Custom Collateral token interface */ function collateral() external view returns (IERC20Custom); /** * @notice Gets total borrow state * @return Rebase Total borrow information */ function totalBorrow() external view returns (Rebase memory); /** * @notice Gets user's borrow part * @param account User address * @return uint256 User's borrow part */ function userBorrowPart(address account) external view returns (uint256); /** * @notice Gets user's collateral share * @param account User address * @return uint256 User's collateral share */ function userCollateralShare( address account ) external view returns (uint256); /** * @notice Gets protocol borrowing limits * @return total Total protocol borrow limit * @return borrowPartPerAddress Per-address borrow limit */ function borrowLimit() external view returns (uint256 total, uint256 borrowPartPerAddress); /** * @notice Gets the DUSX token address * @return IERC20Custom DUSX token interface */ function dusx() external view returns (IERC20Custom); /** * @notice Gets all accounts with active positions * @return address[] Array of account addresses */ function accounts() external view returns (address[] memory); /** * @notice Gets the collateral precision factor * @return uint256 Collateral precision */ function collateralPrecision() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {ILender} from "./ILender.sol"; /** * @title ILenderOwner * @dev Interface for protocol-level lender management and configuration * @notice Defines functionality for: * 1. Interest rate management * 2. Borrow limit control * 3. Risk parameter adjustment */ interface ILenderOwner { /*////////////////////////////////////////////////////////////// INTEREST MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * @notice Updates lender's interest rate configuration * @param lender The lender contract to modify * @param newInterestRate New interest rate value in basis points * @dev Controls: * · Interest accrual * · Yield generation * · Protocol revenue * * Requirements: * · Caller is authorized * · Rate within bounds * · Valid lender contract */ function changeInterestRate( ILender lender, uint256 newInterestRate ) external; /*////////////////////////////////////////////////////////////// LIMIT MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * @notice Updates lender's borrowing constraints * @param lender The lender contract to modify * @param newBorrowLimit New total protocol borrow limit * @param perAddressPart Maximum borrow limit per address * @dev Manages: * · Protocol exposure * · Individual limits * · Risk thresholds * * Requirements: * · Caller is authorized * · Valid limits * · perAddressPart <= newBorrowLimit * * Security: * · Prevents overleveraging * · Controls risk exposure * · Ensures protocol stability */ function changeBorrowLimit( ILender lender, uint256 newBorrowLimit, uint256 perAddressPart ) external; /*////////////////////////////////////////////////////////////// DEPRECATION MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * @notice Checks if a lender contract is deprecated * @param lender The lender address to check * @return bool True if the lender is deprecated, false otherwise * @dev Used to: * · Prevent operations on deprecated markets * · Control market lifecycle * · Manage protocol upgrades * * Security: * · Read-only function * · No state modifications * · Access control not required */ function deprecated(address lender) external view returns (bool); /** * @notice Checks if a lender contract is in manual mode * @param lender The lender address to check * @return bool True if the lender is in manual mode, false otherwise * @dev Used to: * · Determine if borrow limits are managed manually * · Control automatic interest rate adjustments * * Security: * · Read-only function * · No state modifications * · Access control not required */ function manual(address lender) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IERC20Custom} from "./IERC20Custom.sol"; import {ILender} from "../interface/ILender.sol"; import {IMiscHelper} from "../interface/IMiscHelper.sol"; /** * @title ILiquidationHelper * @dev Interface for liquidation assistance operations * @notice Defines comprehensive liquidation functionality including: * 1. Direct liquidation execution * 2. Liquidation amount calculations * 3. Position health checks * 4. Preview and simulation functions * * The helper provides: * · Maximum and partial liquidation support * · Customizable recipient addresses * · Pre-execution liquidation simulations * · Automated DUSX amount calculations */ interface ILiquidationHelper { /*////////////////////////////////////////////////////////////// CONFIGURATION //////////////////////////////////////////////////////////////*/ /*////////////////////////////////////////////////////////////// LIQUIDATION EXECUTION //////////////////////////////////////////////////////////////*/ /** * @notice Liquidates maximum possible amount for an account * @param lender Address of the lending contract * @param account Address to be liquidated * @return collateralAmount Amount of collateral received * @return adjustedBorrowPart Adjusted borrow amount after liquidation * @return requiredDUSXAmount DUSX tokens needed to execute liquidation * @dev Automatically calculates maximum liquidatable amount */ function liquidateMax( ILender lender, address account ) external returns ( uint256 collateralAmount, uint256 adjustedBorrowPart, uint256 requiredDUSXAmount ); /** * @notice Liquidates specific amount for an account * @param lender Address of the lending contract * @param account Address to be liquidated * @param borrowPart Amount of borrow position to liquidate * @return collateralAmount Amount of collateral received * @return adjustedBorrowPart Adjusted borrow amount after liquidation * @return requiredDUSXAmount DUSX tokens needed to execute liquidation * @dev Validates borrowPart against maximum liquidatable amount */ function liquidate( ILender lender, address account, uint256 borrowPart ) external returns ( uint256 collateralAmount, uint256 adjustedBorrowPart, uint256 requiredDUSXAmount ); /*////////////////////////////////////////////////////////////// LIQUIDATION WITH CUSTOM RECIPIENT //////////////////////////////////////////////////////////////*/ /** * @notice Liquidates maximum amount and sends to specified recipient * @param lender Address of the lending contract * @param account Address to be liquidated * @param recipient Address to receive liquidated assets * @dev Combines max liquidation with custom recipient */ function liquidateMaxTo( ILender lender, address account, address recipient ) external; /** * @notice Liquidates specific amount and sends to specified recipient * @param lender Address of the lending contract * @param account Address to be liquidated * @param recipient Address to receive liquidated assets * @param borrowPart Amount of borrow position to liquidate * @dev Combines partial liquidation with custom recipient */ function liquidateTo( ILender lender, address account, address recipient, uint256 borrowPart ) external; /*////////////////////////////////////////////////////////////// LIQUIDATION PREVIEWS //////////////////////////////////////////////////////////////*/ /** * @notice Previews maximum possible liquidation amounts * @param lender Address of the lending contract * @param account Address to check * @return liquidatable Whether the account can be liquidated * @return requiredDUSXAmount DUSX tokens needed for liquidation * @return adjustedBorrowPart Final borrow amount after liquidation * @return returnedCollateralAmount Collateral amount to be received * @dev Simulates liquidation without executing */ function previewMaxLiquidation( ILender lender, address account ) external view returns ( bool liquidatable, uint256 requiredDUSXAmount, uint256 adjustedBorrowPart, uint256 returnedCollateralAmount ); /** * @notice Previews specific liquidation amounts * @param lender Address of the lending contract * @param account Address to check * @param borrowPart Amount of borrow position to liquidate * @return liquidatable Whether the account can be liquidated * @return requiredDUSXAmount DUSX tokens needed for liquidation * @return adjustedBorrowPart Final borrow amount after liquidation * @return returnedCollateralAmount Collateral amount to be received * @dev Simulates partial liquidation without executing */ function previewLiquidation( ILender lender, address account, uint256 borrowPart ) external view returns ( bool liquidatable, uint256 requiredDUSXAmount, uint256 adjustedBorrowPart, uint256 returnedCollateralAmount ); /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Checks if an account is eligible for liquidation * @param lender Address of the lending contract * @param account Address to check * @return bool True if account can be liquidated * @dev Considers collateral ratio and position health */ function isLiquidatable( ILender lender, address account ) external view returns (bool); /** * @notice Returns the DUSX token contract used for liquidations * @return IERC20Custom DUSX token interface * @dev DUSX is required to execute liquidations */ function dusx() external view returns (IERC20Custom); /** * @notice Returns the helper utility contract * @return IMiscHelper Helper interface for additional functions * @dev Helper provides supporting calculations and checks */ function helper() external view returns (IMiscHelper); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {ILender} from "./ILender.sol"; /** * @title IMarketLens * @dev Interface for viewing and analyzing lending market data * @notice Provides functionality for: * 1. Market size analysis * 2. Borrowing metrics * 3. Risk assessment data */ interface IMarketLens { /*////////////////////////////////////////////////////////////// MARKET METRICS //////////////////////////////////////////////////////////////*/ /** * @notice Calculates total borrowed amount from a specific lending market * @param lender Address of the lending market to analyze * @return uint256 Total borrowed amount in base units * @dev Aggregates: * · Active loan positions * · Accrued interest * · Pending liquidations * * Used for: * · Market size analysis * · Risk assessment * · Protocol health monitoring */ function getTotalBorrowed(ILender lender) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IERC20Custom} from "./IERC20Custom.sol"; /** * @title IMinter * @dev Interface for the Minter contract */ interface IMinter { /** * @notice Enables whitelist minting phase */ function enableWhitelistMint() external; /** * @notice Enables public minting phase */ function enablePublicMint() external; /** * @notice Adds a wallet to the whitelist * @param wallet Wallet address to whitelist */ function addToWhitelist(address wallet) external; /** * @notice Mints tokens during whitelist phase * @param stablecoin Stablecoin used for minting * @param stableAmount Amount of stablecoin to mint against */ function whitelistMint( IERC20Custom stablecoin, uint256 stableAmount ) external; /** * @notice Mints tokens during public phase * @param stablecoin Stablecoin used for minting * @param stableAmount Amount of stablecoin to mint against */ function publicMint(IERC20Custom stablecoin, uint256 stableAmount) external; /** * @notice Mints remaining token supply * @param stablecoin Stablecoin used for minting */ function mintRemainingSupply(IERC20Custom stablecoin) external; /** * @notice Sends accumulated DUSX to floor contract */ function sendToFloorDUSX() external; /** * @notice Verifies if a wallet is whitelisted * @param wallet Address to verify * @return bool Whitelist status */ function verifyWallet(address wallet) external view returns (bool); /** * @notice Calculates mint amount for given stablecoin input * @param stablecoin Stablecoin used for calculation * @param stableAmount Amount of stablecoin * @return uint256 Calculated mint amount */ function calcMintAmount( IERC20Custom stablecoin, uint256 stableAmount ) external view returns (uint256); /** * @notice Gets the current token reserve * @return uint256 Current token reserve */ function tokenReserve() external view returns (uint256); /** * @notice Gets the current mint ratio * @return uint256 Current mint ratio */ function getCurrentRatio() external view returns (uint256); /** * @notice Gets the current mint rate * @return uint256 Current mint rate */ function getCurrentRate() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IDynamicInterestRate} from "./IDynamicInterestRate.sol"; import {IFeesDistributor} from "./IFees.sol"; import {IFeesWithdrawer} from "./IFees.sol"; import {IFloor} from "./IFloor.sol"; import {ILender} from "./ILender.sol"; import {ILenderOwner} from "./ILenderOwner.sol"; import {ILiquidationHelper} from "./ILiquidationHelper.sol"; import {IMarketLens} from "./IMarketLens.sol"; import {IPSM} from "./IPSM.sol"; import {IRepayHelper} from "./IRepayHelper.sol"; import {IStakedDUSX} from "./IStakedDUSX.sol"; import {ISupplyHangingCalculator} from "./ISupplyHangingCalculator.sol"; /** * @title IMiscHelper * @dev Interface for miscellaneous helper functions across the protocol * @notice Provides comprehensive helper methods for: * 1. Protocol configuration and parameter management * 2. Floor token operations * 3. Staked DUSX token management * 4. PSM (Peg Stability Module) operations * 5. Lending operations including borrowing and repayment * 6. System-wide view functions * * This interface acts as a central utility hub for coordinating * various protocol components and simplifying complex operations */ interface IMiscHelper { /*////////////////////////////////////////////////////////////// CONFIGURATION FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Sets the supply hanging calculator contract * @param supplyHangingCalculator_ New calculator contract address * @dev Used for calculating supply adjustments */ function setSupplyHangingCalculator( ISupplyHangingCalculator supplyHangingCalculator_ ) external; /** * @notice Sets core protocol parameters and contract addresses * @param repayHelper_ Repayment helper contract * @param liquidationHelper_ Liquidation helper contract * @param dynamicInterestRate_ Interest rate calculator * @param feesDistributor_ Fee distribution contract * @param feesWithdrawer_ Fee withdrawal contract * @param lenderOwner_ Lender owner contract * @param marketLens_ Market data viewer contract * @dev Updates all main protocol component addresses */ function setParameters( IRepayHelper repayHelper_, ILiquidationHelper liquidationHelper_, IDynamicInterestRate dynamicInterestRate_, IFeesDistributor feesDistributor_, IFeesWithdrawer feesWithdrawer_, ILenderOwner lenderOwner_, IMarketLens marketLens_ ) external; /** * @notice Sets the list of active lender contracts * @param lenders_ Array of lender addresses * @dev Updates the protocol's lending markets */ function setLenders(ILender[] memory lenders_) external; /** * @notice Sets the list of PSM contracts * @param pegStabilityModules_ Array of PSM addresses * @dev Updates available stablecoin PSM modules */ function setPegStabilityModules( IPSM[] memory pegStabilityModules_ ) external; /*////////////////////////////////////////////////////////////// FLOOR TOKEN OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Deposits Floor tokens into the protocol * @param amount Amount of Floor tokens to deposit */ function depositFloor(uint256 amount) external; /** * @notice Refunds Floor tokens from the protocol * @param amount Amount of Floor tokens to refund */ function refundFloor(uint256 amount) external; /*////////////////////////////////////////////////////////////// STAKED DUSX OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Deposits DUSX tokens for staking * @param amount Amount of DUSX to stake */ function depositStakedDUSX(uint256 amount) external; /** * @notice Withdraws staked DUSX tokens * @param amount Amount of staked DUSX to withdraw */ function withdrawStakedDUSX(uint256 amount) external; /*////////////////////////////////////////////////////////////// PSM OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Swaps DUSX for stablecoin through PSM * @param psm PSM contract to use for swap * @param receiver Address to receive stablecoins * @param amountDUSX Amount of DUSX to swap */ function psmSwapDUSXForStable( IPSM psm, address receiver, uint256 amountDUSX ) external; /** * @notice Swaps stablecoin for DUSX through PSM * @param psm PSM contract to use for swap * @param receiver Address to receive DUSX * @param amountStable Amount of stablecoin to swap */ function psmSwapStableForDUSX( IPSM psm, address receiver, uint256 amountStable ) external; /*////////////////////////////////////////////////////////////// LENDING OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Withdraws borrowed tokens from vault * @param lender Lender contract to withdraw from * @param amount Amount to withdraw */ function lenderBorrowVaultWithdraw(ILender lender, uint256 amount) external; /** * @notice Executes a borrow operation * @param lender Lender contract to borrow from * @param amount Amount to borrow */ function lenderBorrow(ILender lender, uint256 amount) external; /** * @notice Repays borrowed tokens * @param lender Lender contract to repay to * @param payer Address paying the debt * @param to Address receiving any excess * @param skim Whether to skim tokens from contract * @param part Amount of borrow part to repay */ function lenderRepay( ILender lender, address payer, address to, bool skim, uint256 part ) external; /** * @notice Executes liquidation for multiple users * @param lender Lender contract to liquidate from * @param liquidator Address performing liquidation * @param users Array of addresses to liquidate * @param maxBorrowParts Maximum borrow parts to liquidate per user * @param to Address to receive liquidated assets */ function lenderLiquidate( ILender lender, address liquidator, address[] memory users, uint256[] memory maxBorrowParts, address to ) external; /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Returns current APR for staked DUSX * @return uint256 Annual percentage rate */ function aprStakedDUSX() external view returns (uint256); /** * @notice Returns repayment helper contract */ function repayHelper() external view returns (IRepayHelper); /** * @notice Returns liquidation helper contract */ function liquidationHelper() external view returns (ILiquidationHelper); /** * @notice Returns dynamic interest rate calculator */ function dynamicInterestRate() external view returns (IDynamicInterestRate); /** * @notice Returns floor token contract */ function floor() external view returns (IFloor); /** * @notice Returns fees distributor contract */ function feesDistributor() external view returns (IFeesDistributor); /** * @notice Returns fees withdrawer contract */ function feesWithdrawer() external view returns (IFeesWithdrawer); /** * @notice Returns lender contract at specified index * @param index Position in lenders array */ function lenders(uint256 index) external view returns (ILender); /** * @notice Returns total number of lender contracts */ function lendersLength() external view returns (uint256); /** * @notice Returns lender owner contract */ function lenderOwner() external view returns (ILenderOwner); /** * @notice Returns market lens contract */ function marketLens() external view returns (IMarketLens); /** * @notice Returns PSM contract at specified index * @param index Position in PSM array */ function pegStabilityModules(uint256 index) external view returns (IPSM); /** * @notice Returns total number of PSM contracts */ function pegStabilityModulesLength() external view returns (uint256); /** * @notice Returns staked DUSX token contract */ function stDUSX() external view returns (IStakedDUSX); /** * @notice Returns supply hanging calculator contract */ function supplyHangingCalculator() external view returns (ISupplyHangingCalculator); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IOracle * @dev Interface for basic price feed operations * @notice Defines functionality for: * 1. Asset price retrieval * 2. Price precision handling */ interface IOracle { /*////////////////////////////////////////////////////////////// PRICE QUERIES //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves current asset price * @param asset Address of the asset to price * @return uint256 Current price in base units with precision * @dev Provides: * · Latest price data * · Standardized precision * · Asset valuation * * Note: Check implementation for specific precision details */ function getPrice(address asset) external view returns (uint256); } /** * @title ITwapOracle * @dev Interface for time-weighted average price calculations * @notice Defines functionality for: * 1. TWAP updates * 2. Time-weighted calculations * 3. Price smoothing */ interface ITwapOracle { /*////////////////////////////////////////////////////////////// TWAP OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Updates time-weighted average price * @param asset Address of the asset to update * @return uint256 New TWAP value in base units * @dev Calculates: * · Time-weighted price * · Cumulative values * · Price averages * * Features: * · Manipulation resistance * · Smoothing effect * · Historical tracking */ function updateTwap(address asset) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IERC20Custom} from "./IERC20Custom.sol"; /** * @title IPSM * @dev Interface for Peg Stability Module (PSM) operations * @notice Defines functionality for: * 1. Stablecoin/DUSX swaps * 2. Peg maintenance * 3. Supply tracking */ interface IPSM { /*////////////////////////////////////////////////////////////// SWAP OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Executes stablecoin to DUSX swap * @param msgSender Address initiating the swap * @param receiver Address receiving the DUSX * @param stableTokenAmount Amount of stablecoins to swap * @dev Handles: * · Stablecoin deposit * · DUSX minting * · Supply tracking */ function swapStableForDUSX( address msgSender, address receiver, uint256 stableTokenAmount ) external; /** * @notice Executes DUSX to stablecoin swap * @param msgSender Address initiating the swap * @param receiver Address receiving the stablecoins * @param stableTokenAmount Amount of stablecoins to receive * @dev Handles: * · DUSX burning * · Stablecoin release * · Supply adjustment */ function swapDUSXForStable( address msgSender, address receiver, uint256 stableTokenAmount ) external; /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves the stablecoin token contract * @return IERC20Custom Stablecoin token interface * @dev Used for: * · Token transfers * · Balance checks * · Allowance verification */ function stableToken() external view returns (IERC20Custom); /** * @notice Returns total DUSX tokens minted through PSM * @return uint256 Total minted amount in base units * @dev Tracks: * · Total supply impact * · PSM utilization * · Protocol growth metrics */ function dusxMinted() external view returns (uint256); /** * @notice Returns the maximum amount of DUSX that can be minted through PSM * @return uint256 Maximum mintable amount in base units * @dev Used for: * · Supply control * · Risk management * · Protocol safety */ function dusxMintCap() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IERC20Custom} from "./IERC20Custom.sol"; import {ILender} from "./ILender.sol"; import {IMiscHelper} from "./IMiscHelper.sol"; /** * @title IRepayHelper * @dev Interface for streamlined loan repayment operations and management * @notice Defines functionality for: * 1. Loan repayment processing * 2. Multi-loan management * 3. Helper contract integration * 4. Token interactions */ interface IRepayHelper { /*////////////////////////////////////////////////////////////// CONFIGURATION //////////////////////////////////////////////////////////////*/ /*////////////////////////////////////////////////////////////// REPAYMENT OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Processes partial loan repayment * @param lender Address of the lending contract * @param to Address whose loan is being repaid * @param amount Amount to repay in base units * @return part Share of the loan repaid * @dev Handles: * · Token transfers * · Loan accounting * · Share calculations * * Requirements: * · Amount > 0 * · Sufficient balance * · Valid addresses */ function repayAmount( ILender lender, address to, uint256 amount ) external returns (uint256 part); /** * @notice Processes complete loan repayment * @param lender Address of the lending contract * @param to Address whose loan is being repaid * @return amount Total amount repaid in base units * @dev Manages: * · Full debt calculation * · Complete repayment * · Account settlement * * Effects: * · Clears entire debt * · Updates balances * · Emits events */ function repayTotal( ILender lender, address to ) external returns (uint256 amount); /** * @notice Processes multiple complete loan repayments * @param lender Address of the lending contract * @param tos Array of addresses whose loans are being repaid * @return amount Total amount repaid across all loans * @dev Executes: * · Batch processing * · Multiple settlements * · Aggregate accounting * * Optimizations: * · Gas efficient * · Bulk processing * · Single transaction */ function repayTotalMultiple( ILender lender, address[] calldata tos ) external returns (uint256 amount); /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves DUSX token contract * @return IERC20Custom Interface of the DUSX token * @dev Used for: * · Token operations * · Balance checks * · Allowance verification */ function dusx() external view returns (IERC20Custom); /** * @notice Retrieves helper contract * @return IMiscHelper Interface of the helper contract * @dev Provides: * · Helper functionality * · Integration access * · Utility methods */ function helper() external view returns (IMiscHelper); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {IERC20Token} from "./IERC20Token.sol"; /** * @title IStableOwner Interface * @dev Interface for StableOwner contract that manages stable token supply * @notice Defines the external interface for stable token supply management */ interface IStableOwner { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ /// @notice Emitted when stable token contract is updated /// @param stable New stable token contract address event StableSet(IERC20Token indexed stable); /// @notice Emitted when new tokens are minted /// @param account Recipient of minted tokens /// @param amount Amount of tokens minted event TokensMinted(address indexed account, uint256 amount); /// @notice Emitted when tokens are burned /// @param account Account tokens were burned from /// @param amount Amount of tokens burned event TokensBurned(address indexed account, uint256 amount); /*////////////////////////////////////////////////////////////// FUNCTIONS //////////////////////////////////////////////////////////////*/ /// @notice Updates the stable token contract address /// @param stable_ New stable token contract address function setStable(IERC20Token stable_) external; /// @notice Creates new stable tokens /// @param account Address to receive minted tokens /// @param amount Number of tokens to mint function mint(address account, uint256 amount) external; /// @notice Destroys existing stable tokens /// @param account Address to burn tokens from /// @param amount Number of tokens to burn function burn(address account, uint256 amount) external; /// @notice The managed stable token contract /// @return The IERC20Token interface of the stable token function stable() external view returns (IERC20Token); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IStakedDUSX * @dev Interface for staked DUSX token operations and reward distribution * @notice Defines functionality for: * 1. DUSX token staking * 2. Reward distribution * 3. Position management */ interface IStakedDUSX { /*////////////////////////////////////////////////////////////// REWARD DISTRIBUTION //////////////////////////////////////////////////////////////*/ /** * @notice Distributes protocol fees as staking rewards * @param amount Amount of fees to distribute in base units * @dev Handles: * · Pro-rata distribution * · Reward accounting * · Distribution events * * Rewards are: * · Automatically calculated * · Immediately available * · Proportional to stake */ function distributeFees(uint256 amount) external; /** * @notice Claims pending fee rewards for the caller * @return claimedAmount Amount of fees claimed * @dev Allows users to manually claim their accumulated fees */ function claimFees() external returns (uint256 claimedAmount); /*////////////////////////////////////////////////////////////// STAKING OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Processes DUSX token deposits for staking * @param from Address providing the tokens * @param to Address receiving the staked position * @param amount Quantity of tokens to stake in base units * @dev Manages: * · Token transfers * · Position creation * · Reward calculations * * Supports: * · Direct deposits * · Delegated deposits * · Position tracking */ function deposit(address from, address to, uint256 amount) external; /** * @notice Initiates a withdrawal from staked DUSX * @param amount Amount of tokens to withdraw */ function beginWithdrawal(uint256 amount) external; /** * @notice Processes withdrawal of staked DUSX tokens * @param account Address withdrawing tokens * @dev Handles: * · Position updates * · Reward claims * · Token transfers * * Ensures: * · Sufficient balance * · Reward distribution * · Clean exit */ function withdraw(address account) external; /** * @notice Views pending unclaimed fees for an account * @param account Address to check for pending fees * @return pendingAmount Amount of pending fees available to claim * @dev Calculates based on the fee accumulator and account's last claimed value */ function pendingFees( address account ) external view returns (uint256 pendingAmount); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title ISupplyHangingCalculator * @dev Interface for calculating and managing token supply adjustments * @notice Defines functionality for: * 1. Supply hanging calculations * 2. Safety margin management * 3. Risk-adjusted metrics */ interface ISupplyHangingCalculator { /*////////////////////////////////////////////////////////////// SAFETY PARAMETERS //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves current safety margin for supply calculations * @return uint256 Safety margin percentage scaled by 1e18 * @dev Used for: * · Risk adjustment * · Supply buffer * · Protocol protection */ function safetyMargin() external view returns (uint256); /*////////////////////////////////////////////////////////////// SUPPLY HANGING CALCULATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Calculates current supply hanging with safety margins * @return uint256 Risk-adjusted supply hanging in base units * @dev Includes: * · Safety margin application * · Risk adjustments * · Protocol constraints * * Used for: * · Safe supply management * · Conservative adjustments * · Risk-aware operations */ function getSupplyHanging() external view returns (uint256); /** * @notice Calculates raw supply hanging without safety margins * @return uint256 Unadjusted supply hanging in base units * @dev Provides: * · Raw calculations * · No safety buffers * · Maximum theoretical values * * Used for: * · Analysis purposes * · Maximum bounds * · Stress testing */ function getSupplyHangingUnsafe() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; import {Rebase} from "../library/AuxRebase.sol"; import {IERC20Custom} from "./IERC20Custom.sol"; /** * @title IVault * @dev Interface for advanced vault operations with elastic share system * @notice Defines functionality for: * 1. Token custody and management * 2. Share-based accounting * 3. Elastic supply mechanics * 4. Amount/share conversions */ interface IVault { /*////////////////////////////////////////////////////////////// DEPOSIT OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Processes token deposits into vault * @param token Token contract to deposit * @param from Source of tokens * @param to Recipient of shares * @param amount Token amount (in base units, 0 for share-based) * @param share Share amount (0 for amount-based) * @return amountIn Actual tokens deposited * @return shareIn Actual shares minted * @dev Handles: * · Token transfers * · Share minting * · Balance updates * * Requirements: * · Valid token contract * · Authorized caller * · Sufficient balance * · Either amount or share > 0 * * Note: Only one of amount/share should be non-zero */ function deposit( IERC20Custom token, address from, address to, uint256 amount, uint256 share ) external returns (uint256 amountIn, uint256 shareIn); /*////////////////////////////////////////////////////////////// WITHDRAWAL OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Processes token withdrawals from vault * @param token Token contract to withdraw * @param from Source of shares * @param to Recipient of tokens * @param amount Token amount (in base units, 0 for share-based) * @param share Share amount (0 for amount-based) * @return amountOut Actual tokens withdrawn * @return shareOut Actual shares burned * @dev Manages: * · Share burning * · Token transfers * · Balance updates * * Requirements: * · Valid token contract * · Sufficient shares * · Either amount or share > 0 * · Authorized withdrawal * * Security: * · Validates balances * · Checks permissions * · Updates state atomically */ function withdraw( IERC20Custom token, address from, address to, uint256 amount, uint256 share ) external returns (uint256 amountOut, uint256 shareOut); /*////////////////////////////////////////////////////////////// SHARE TRANSFERS //////////////////////////////////////////////////////////////*/ /** * @notice Transfers vault shares between accounts * @param token Associated token contract * @param from Source of shares * @param to Recipient of shares * @param share Amount of shares to transfer * @dev Executes: * · Direct share movement * · Balance updates * · Event emission * * Requirements: * · Sufficient share balance * · Valid addresses * · Share amount > 0 * * Note: Bypasses amount calculations for efficiency */ function transfer( IERC20Custom token, address from, address to, uint256 share ) external; /*////////////////////////////////////////////////////////////// BALANCE QUERIES //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves account's vault share balance * @param token Token contract to query * @param account Address to check * @return uint256 Share balance * @dev Provides: * · Raw share balance * · Without conversion * · Current state * * Use toAmount() to convert to token amount */ function balanceOf( IERC20Custom token, address account ) external view returns (uint256); /*////////////////////////////////////////////////////////////// CONVERSION OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Converts token amount to vault shares * @param token Token contract for conversion * @param amount Amount of tokens to convert * @param roundUp Whether to round up result * @return share Equivalent share amount * @dev Calculates: * · Share equivalent * · Based on totals * · Handles precision * * Rounding: * true = ceiling (≥) * false = floor (≤) */ function toShare( IERC20Custom token, uint256 amount, bool roundUp ) external view returns (uint256 share); /** * @notice Converts vault shares to token amount * @param token Token contract for conversion * @param share Amount of shares to convert * @param roundUp Whether to round up result * @return amount Equivalent token amount * @dev Calculates: * · Token equivalent * · Based on totals * · Handles precision * * Rounding: * true = ceiling (≥) * false = floor (≤) */ function toAmount( IERC20Custom token, uint256 share, bool roundUp ) external view returns (uint256 amount); /** * @notice Gets the list of active controllers * @return Array of controller addresses */ function getControllers() external view returns (address[] memory); /*////////////////////////////////////////////////////////////// VAULT TOTALS //////////////////////////////////////////////////////////////*/ /** * @notice Retrieves vault's total supply tracking * @param token Token contract to query * @return vaultTotals Rebase struct containing: * · elastic: Total token amount * · base: Total shares * @dev Provides: * · Current vault state * · Supply tracking * · Conversion basis * * Used for: * · Share calculations * · Amount conversions * · State validation */ function totals( IERC20Custom token ) external view returns (Rebase memory vaultTotals); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title IVoteEscrowedSTTX * @dev Interface for vote-escrowed STTX (veSTTX) token operations * @notice Defines functionality for: * 1. Token withdrawal management * 2. Escrow position handling * 3. Voting power release */ interface IVoteEscrowedSTTX { /*////////////////////////////////////////////////////////////// WITHDRAWAL OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Processes withdrawal of escrowed STTX tokens * @dev Handles: * · Lock period verification * · Position liquidation * · Token transfers * * Requirements: * · Lock period expired * · Active position exists * · Caller is position owner * * Effects: * · Releases locked tokens * · Removes voting power * · Clears escrow position */ function withdraw() external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.24 <0.9.0; /** * @title Rebase Library * @dev Library for handling elastic supply token calculations and adjustments * @notice This library provides mathematical operations for elastic/base token conversions * and supply adjustments. It handles two key concepts: * * 1. Elastic Supply: The actual total supply that can expand or contract * 2. Base Supply: The underlying base amount that remains constant */ /*////////////////////////////////////////////////////////////// TYPES //////////////////////////////////////////////////////////////*/ /** * @dev Core data structure for elastic supply tracking * @param elastic Current elastic (rebased) supply * @param base Current base (non-rebased) supply */ struct Rebase { uint256 elastic; uint256 base; } /** * @title AuxRebase * @dev Auxiliary functions for elastic supply calculations * @notice Provides safe mathematical operations for elastic/base conversions * with optional rounding control */ library AuxRebase { /*////////////////////////////////////////////////////////////// ELASTIC SUPPLY OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Increases the elastic supply * @param total Current total supply state * @param elastic Amount to add to elastic supply * @return newElastic Updated elastic supply after addition */ function addElastic( Rebase storage total, uint256 elastic ) internal returns (uint256 newElastic) { newElastic = total.elastic += elastic; } /** * @notice Decreases the elastic supply * @param total Current total supply state * @param elastic Amount to subtract from elastic supply * @return newElastic Updated elastic supply after subtraction */ function subElastic( Rebase storage total, uint256 elastic ) internal returns (uint256 newElastic) { newElastic = total.elastic -= elastic; } /*////////////////////////////////////////////////////////////// CONVERSION OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Converts an elastic amount to its base amount * @param total Current total supply state * @param elastic Amount of elastic tokens to convert * @param roundUp If true, rounds up the result * @return base Equivalent amount in base units * @dev * · If elastic supply is 0, returns elastic amount as base * · Handles potential precision loss during conversion * · Rounding can cause slight variations in converted amounts * · Recommended for scenarios requiring precise supply tracking * * Rounding Behavior: * · roundUp = false: Always rounds down (truncates) * · roundUp = true: Rounds up if there's a fractional remainder * * Edge Cases: * · total.elastic == 0: Returns input elastic as base * · Potential for minimal precision differences */ function toBase( Rebase memory total, uint256 elastic, bool roundUp ) internal pure returns (uint256 base) { if (total.elastic == 0) { base = elastic; } else { base = (elastic * total.base) / total.elastic; if (roundUp && (base * total.elastic) / total.base < elastic) { base++; } } } /** * @notice Converts a base amount to its elastic amount * @param total Current total supply state * @param base Amount of base tokens to convert * @param roundUp If true, rounds up the result * @return elastic Equivalent amount in elastic units * @dev * · If base supply is 0, returns base amount as elastic * · Handles potential precision loss during conversion * · Rounding can cause slight variations in converted amounts * · Recommended for scenarios requiring precise supply tracking * * Rounding Behavior: * · roundUp = false: Always rounds down (truncates) * · roundUp = true: Rounds up if there's a fractional remainder * * Edge Cases: * · total.base == 0: Returns input base as elastic * · Potential for minimal precision differences */ function toElastic( Rebase memory total, uint256 base, bool roundUp ) internal pure returns (uint256 elastic) { if (total.base == 0) { elastic = base; } else { elastic = (base * total.elastic) / total.base; if (roundUp && (elastic * total.base) / total.elastic < base) { elastic++; } } } /*////////////////////////////////////////////////////////////// COMBINED OPERATIONS //////////////////////////////////////////////////////////////*/ /** * @notice Adds elastic tokens and calculates corresponding base amount * @param total Current total supply state * @param elastic Amount of elastic tokens to add * @param roundUp If true, rounds up base conversion * @return (Rebase, uint256) Updated total supply and calculated base amount */ function add( Rebase memory total, uint256 elastic, bool roundUp ) internal pure returns (Rebase memory, uint256 base) { base = toBase(total, elastic, roundUp); total.elastic += elastic; total.base += base; return (total, base); } /** * @notice Subtracts base tokens and calculates corresponding elastic amount * @param total Current total supply state * @param base Amount of base tokens to subtract * @param roundUp If true, rounds up elastic conversion * @return (Rebase, uint256) Updated total supply and calculated elastic amount */ function sub( Rebase memory total, uint256 base, bool roundUp ) internal pure returns (Rebase memory, uint256 elastic) { elastic = toElastic(total, base, roundUp); total.elastic -= elastic; total.base -= base; return (total, elastic); } /** * @notice Adds specific amounts to both elastic and base supplies * @param total Current total supply state * @param elastic Amount of elastic tokens to add * @param base Amount of base tokens to add * @return Rebase Updated total supply after addition */ function add( Rebase memory total, uint256 elastic, uint256 base ) internal pure returns (Rebase memory) { total.elastic += elastic; total.base += base; return total; } /** * @notice Subtracts specific amounts from both elastic and base supplies * @param total Current total supply state * @param elastic Amount of elastic tokens to subtract * @param base Amount of base tokens to subtract * @return Rebase Updated total supply after subtraction */ function sub( Rebase memory total, uint256 elastic, uint256 base ) internal pure returns (Rebase memory) { total.elastic -= elastic; total.base -= base; return total; } }
{ "viaIR": true, "evmVersion": "paris", "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IBaseContracts","name":"baseContracts_","type":"address"},{"internalType":"address","name":"treasury_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApproveFailed","type":"error"},{"inputs":[],"name":"EmptyArray","type":"error"},{"inputs":[],"name":"InvalidMintAmount","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"InvalidOwner","type":"error"},{"inputs":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"MaxStableRangeCalculationFailed","type":"error"},{"inputs":[],"name":"MintAlreadyActive","type":"error"},{"inputs":[{"internalType":"uint256","name":"stableAmount","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"MintAmountCalculationFailed","type":"error"},{"inputs":[],"name":"MintNotActive","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"TokenReserveIsNotLowEnough","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"UnauthorizedAccount","type":"error"},{"inputs":[],"name":"UnsupportedStablecoin","type":"error"},{"inputs":[],"name":"WalletNotWhitelisted","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"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":[],"name":"PublicMintEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"WalletWhitelisted","type":"event"},{"anonymous":false,"inputs":[],"name":"WhitelistMintEnabled","type":"event"},{"inputs":[],"name":"TREASURY_ALLOCATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"addWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"wallets","type":"address[]"}],"name":"addWalletBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Custom","name":"stablecoin","type":"address"},{"internalType":"uint256","name":"stableAmount","type":"uint256"}],"name":"calcMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Custom","name":"stablecoin","type":"address"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"calcStableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dusx","outputs":[{"internalType":"contract IERC20Token","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enablePublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableWhitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"floor","outputs":[{"internalType":"contract IFloor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"helper","outputs":[{"internalType":"contract IMiscHelper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Custom","name":"stablecoin","type":"address"}],"name":"mintRemainingSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pegStabilityModules","outputs":[{"internalType":"contract IPSM","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Custom","name":"stablecoin","type":"address"},{"internalType":"uint256","name":"stableAmount","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"publicMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sendToFloorDUSX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stables","outputs":[{"internalType":"contract IERC20Custom","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sttx","outputs":[{"internalType":"contract IERC20TokenRebase","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"verifyWallet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Custom","name":"stablecoin","type":"address"},{"internalType":"uint256","name":"stableAmount","type":"uint256"}],"name":"whitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedWallets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
61012060405234620000e55762000020620000196200020c565b9062001036565b6200002a620000eb565b613a3962001ed782396080518181816108e30152613660015260a051818181610c47015281816111f1015281816112850152818161171801528181611803015281816118930152818161197901528181611a6101528181611c18015281816123220152818161240e015281816126a70152818161296a01528181613026015281816130d1015261314f015260c051816103d0015260e0518181816104b601526132cf0152610100518181816102c901526134e10152613a3990f35b620000f1565b60405190565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b906200012290620000f6565b810190811060018060401b038211176200013b57604052565b62000100565b906200015862000150620000eb565b928362000116565b565b600080fd5b60018060a01b031690565b62000175906200015f565b90565b62000183906200016a565b90565b620001918162000178565b036200019957565b600080fd5b90505190620001ad8262000186565b565b620001ba816200016a565b03620001c257565b600080fd5b90505190620001d682620001af565b565b9190604083820312620002065780620001f96200020392600086016200019e565b93602001620001c7565b90565b6200015a565b6200022f6200591080380380620002238162000141565b928339810190620001d8565b9091565b90565b6200024f6200024962000255926200015f565b62000233565b6200015f565b90565b620002639062000236565b90565b620002719062000258565b90565b60e01b90565b62000285906200016a565b90565b62000293816200027a565b036200029b57565b600080fd5b90505190620002af8262000288565b565b90602082820312620002ce57620002cb91600001620002a0565b90565b6200015a565b60000190565b620002e4620000eb565b3d6000823e3d90fd5b60001b90565b906200030660018060a01b0391620002ed565b9181191691161790565b6200031b9062000236565b90565b620003299062000310565b90565b90565b90620003496200034362000351926200031e565b6200032c565b8254620002f3565b9055565b62000360906200016a565b90565b6200036e8162000355565b036200037657565b600080fd5b905051906200038a8262000363565b565b90602082820312620003a957620003a6916000016200037b565b90565b6200015a565b620003ba906200016a565b90565b620003c881620003af565b03620003d057565b600080fd5b90505190620003e482620003bd565b565b9060208282031262000403576200040091600001620003d5565b90565b6200015a565b62000414906200016a565b90565b620004228162000409565b036200042a57565b600080fd5b905051906200043e8262000417565b565b906020828203126200045d576200045a916000016200042f565b90565b6200015a565b60001c90565b60018060a01b031690565b62000483620004899162000463565b62000469565b90565b62000498905462000474565b90565b620004a69062000258565b90565b620004b5905162000355565b90565b620004c39062000258565b90565b620004d29051620003af565b90565b620004e09062000258565b90565b620004ef905162000409565b90565b620004fd9062000258565b90565b90565b90565b6200051f62000519620005259262000500565b62000233565b62000503565b90565b60018060401b0381116200053f5760208091020190565b62000100565b906200055b620005558362000528565b62000141565b918252565b369037565b9062000590620005758362000545565b9260208062000585869362000528565b920191039062000560565b565b6200059d906200016a565b90565b620005ab8162000592565b03620005b357565b600080fd5b90505190620005c782620005a0565b565b90602082820312620005e657620005e391600001620005b8565b90565b6200015a565b634e487b7160e01b600052603260045260246000fd5b5190565b90620006128262000602565b81101562000624576020809102010190565b620005ec565b90565b62000646620006406200064c926200062a565b62000233565b62000503565b90565b906200065b9062000592565b9052565b90565b6200067b6200067562000681926200065f565b62000233565b62000503565b90565b62000690905162000592565b90565b6200069e9062000258565b90565b620006ba620006b4620006c0926200062a565b62000233565b6200015f565b90565b620006ce90620006a1565b90565b5490565b634e487b7160e01b600052601160045260246000fd5b620006fd620007049193929362000503565b9262000503565b916200071283820262000503565b9281840414901517156200072257565b620006d5565b600190818003010490565b600052602060002090565b1b90565b91906008620007629102916200075b600019846200073e565b926200073e565b9181191691161790565b620007856200077f6200078b9262000503565b62000233565b62000503565b90565b90565b9190620007ac620007a6620007b5936200076c565b6200078e565b90835462000742565b9055565b600090565b620007d491620007cd620007b9565b9162000791565b565b5b818110620007e3575050565b80620007f36000600193620007be565b01620007d7565b90918281106200080a575b505050565b6200082f62000828620008216200083b9562000728565b9262000728565b9262000733565b918201910190620007d6565b38808062000805565b90680100000000000000008111620008725781620008666200087093620006d1565b90828155620007fa565b565b62000100565b60200190565b60018060a01b031690565b90565b620008978262000602565b9160018060401b0383116200090657620008ca620008c3600192620008bd868662000844565b62000878565b9262000733565b92049160005b838110620008de5750505050565b6001906020620008f8620008f28662000684565b62000889565b9401938184015501620008d0565b62000100565b9062000918916200088c565b565b60018060401b038111620009315760208091020190565b62000100565b906200094d62000947836200091a565b62000141565b918252565b369037565b9062000982620009678362000937565b926020806200097786936200091a565b920191039062000952565b565b6200098f906200016a565b90565b6200099d8162000984565b03620009a557565b600080fd5b90505190620009b98262000992565b565b90602082820312620009d857620009d591600001620009aa565b90565b6200015a565b5190565b90620009ee82620009de565b81101562000a00576020809102010190565b620005ec565b9062000a129062000984565b9052565b62000a22905162000984565b90565b62000a309062000258565b90565b5490565b600190818003010490565b600052602060002090565b5b81811062000a5a575050565b8062000a6a6000600193620007be565b0162000a4e565b909182811062000a81575b505050565b62000aa662000a9f62000a9862000ab29562000a37565b9262000a37565b9262000a42565b91820191019062000a4d565b38808062000a7c565b9068010000000000000000811162000ae9578162000add62000ae79362000a33565b9082815562000a71565b565b62000100565b60200190565b60018060a01b031690565b90565b62000b0e82620009de565b9160018060401b03831162000b7d5762000b4162000b3a60019262000b34868662000abb565b62000aef565b9262000a42565b92049160005b83811062000b555750505050565b600190602062000b6f62000b698662000a16565b62000b00565b940193818401550162000b47565b62000100565b9062000b8f9162000b03565b565b60018060401b03811162000ba55760200290565b62000100565b62000bba62000bc09162000b91565b62000141565b90565b90565b61ffff1690565b62000be662000be062000bec9262000bc3565b62000233565b62000bc6565b90565b9062000bfb9062000bc6565b9052565b90565b62000c1b62000c1562000c219262000bff565b62000233565b62000bc6565b90565b90565b62000c4062000c3a62000c469262000c24565b62000233565b62000bc6565b90565b50600a90565b600190818003010490565b90565b5b81811062000c6a575050565b8062000c7a6000600193620007be565b0162000c5e565b909182811062000c91575b505050565b62000cb662000caf62000ca862000cc29562000c4f565b9262000c4f565b9262000c5a565b91820191019062000c5d565b38808062000c8c565b9068010000000000000000811162000cf6578162000ced62000cf49362000c49565b9062000c81565b565b62000100565b50600a90565b62000d0e905162000bc6565b90565b90565b62000d1f8262000cfc565b9160018060401b03831162000d8e5762000d5262000d4b60019262000d45868662000ccb565b62000d11565b9262000c5a565b92049160005b83811062000d665750505050565b600190602062000d8062000d7a8662000d02565b6200078e565b940193818401550162000d58565b62000100565b9062000da09162000d14565b565b60ff1690565b62000db38162000da2565b0362000dbb57565b600080fd5b9050519062000dcf8262000da8565b565b9060208282031262000dee5762000deb9160000162000dc0565b90565b6200015a565b62000dff9062000da2565b604d811162000e0e57600a0a90565b620006d5565b90565b62000e3062000e2a62000e369262000e14565b62000233565b62000503565b90565b60209181520190565b62000e4d9062000a25565b9052565b9062000e608160209362000e42565b0190565b62000e7362000e799162000463565b62000af5565b90565b62000e88905462000e64565b90565b60010190565b9062000eb462000ead62000ea58462000a33565b809362000e39565b9262000a42565b9060005b81811062000ec65750505090565b90919262000eec62000ee560019262000edf8762000e7c565b62000e51565b9462000e8b565b910191909162000eb8565b9062000f039162000e91565b90565b9062000f2c62000f249262000f1a620000eb565b9384809262000ef7565b038362000116565b565b62000f399062000f06565b90565b62000f479062000693565b9052565b9062000f5a8160209362000f3c565b0190565b62000f6d62000f739162000463565b6200087e565b90565b62000f82905462000f5e565b90565b60010190565b9062000fae62000fa762000f9f84620006d1565b809362000e39565b9262000733565b9060005b81811062000fc05750505090565b90919262000fe662000fdf60019262000fd98762000f76565b62000f4b565b9462000f85565b910191909162000fb2565b9062000ffd9162000f8b565b90565b90620010266200101e9262001014620000eb565b9384809262000ff1565b038362000116565b565b620010339062001000565b90565b6200104062001a7f565b620010556200104f8262000266565b62001ab7565b620010608262001ab7565b6200108a6020620010718362000266565b6363b0e66a9062001081620000eb565b93849262000274565b825281806200109c60048201620002d4565b03915afa801562001a2b57620010be91600091620019f6575b5060026200032f565b620010e86020620010cf8362000266565b6396df10c090620010df620000eb565b93849262000274565b82528180620010fa60048201620002d4565b03915afa908115620019f057600091620019bb575b506080526200113d6020620011248362000266565b63ec4d80199062001134620000eb565b93849262000274565b825281806200114f60048201620002d4565b03915afa908115620019b55760009162001980575b5060a052620011926020620011798362000266565b63406953639062001189620000eb565b93849262000274565b82528180620011a460048201620002d4565b03915afa9081156200197a5760009162001945575b5060c052620011dd620011d7620011d160026200048c565b6200049b565b62001ab7565b620011fd620011f7620011f16080620004a9565b620004b8565b62001ab7565b6200121d620012176200121160a0620004c6565b620004d5565b62001ab7565b6200123d620012376200123160c0620004e3565b620004f2565b62001ab7565b620012536200124d600262000506565b62000565565b906200127e6020620012658362000266565b63b5cab3629062001275620000eb565b93849262000274565b825281806200129060048201620002d4565b03915afa80156200193f57620012f392620012d4620012da926020946000916200190b575b50620012ce87620012c760006200062d565b9062000606565b6200064f565b62000266565b63d4aaf8b990620012ea620000eb565b93849262000274565b825281806200130560048201620002d4565b03915afa801562001905576200133d91600091620018d0575b50620013378362001330600162000662565b9062000606565b6200064f565b62001369620013636200135d836200135660006200062d565b9062000606565b62000684565b62000693565b6200138a620013836200137d6000620006c3565b6200016a565b916200016a565b1480156200187b575b6200185457620013a58160046200090c565b62001407620013bf620013b9600262000506565b62000957565b916020620013ee620013e8620013e284620013db60006200062d565b9062000606565b62000684565b62000693565b63a9d75b2b90620013fe620000eb565b94859262000274565b825281806200141960048201620002d4565b03915afa9081156200184e576200147f620014796200148592620014666020956200149e976000916200181a575b5062001460896200145960006200062d565b90620009e2565b62000a06565b62001472600162000662565b9062000606565b62000684565b62000693565b63a9d75b2b9062001495620000eb565b93849262000274565b82528180620014b060048201620002d4565b03915afa80156200181457620014e891600091620017df575b50620014e283620014db600162000662565b90620009e2565b62000a06565b620015146200150e62001508836200150160006200062d565b90620009e2565b62000a16565b62000a25565b620015356200152e620015286000620006c3565b6200016a565b916200016a565b1480156200178a575b62001763576200155090600362000b83565b60e0526200167b62001563600a62000bab565b6200157e6200157461111c62000bcd565b6000830162000bef565b620015996200158f61111c62000bcd565b6020830162000bef565b620015b4620015aa61104f62000c02565b6040830162000bef565b620015cf620015c561104f62000c02565b6060830162000bef565b620015ea620015e0610fa862000c27565b6080830162000bef565b62001605620015fb610fa862000c27565b60a0830162000bef565b6200162062001616610fa862000c27565b60c0830162000bef565b6200163b62001631610fa862000c27565b60e0830162000bef565b620016576200164c610fa862000c27565b610100830162000bef565b6200167362001668610fa862000c27565b610120830162000bef565b600562000d94565b620016b5630ae64c6860206200169c6200169660a0620004c6565b620004d5565b63313ce56790620016ac620000eb565b94859262000274565b82528180620016c760048201620002d4565b03915afa80156200175d57620016f0620016f791620016fd9460009162001728575b5062000df4565b9162000e17565b620006eb565b610100526200172660036200171f6200171860049262000f2e565b9162001028565b9062001baf565b565b6200174e915060203d811162001755575b62001745818362000116565b81019062000dd1565b38620016e9565b503d62001739565b620002da565b6200176d620000eb565b63d92e233d60e01b8152806200178660048201620002d4565b0390fd5b50620017b7620017b1620017ab83620017a4600162000662565b90620009e2565b62000a16565b62000a25565b620017d8620017d1620017cb6000620006c3565b6200016a565b916200016a565b146200153e565b62001805915060203d81116200180c575b620017fc818362000116565b810190620009bb565b38620014c9565b503d620017f0565b620002da565b6200183f9150873d811162001846575b62001836818362000116565b810190620009bb565b3862001447565b503d6200182a565b620002da565b6200185e620000eb565b63d92e233d60e01b8152806200187760048201620002d4565b0390fd5b50620018a8620018a26200189c8362001895600162000662565b9062000606565b62000684565b62000693565b620018c9620018c2620018bc6000620006c3565b6200016a565b916200016a565b1462001393565b620018f6915060203d8111620018fd575b620018ed818362000116565b810190620005c9565b386200131e565b503d620018e1565b620002da565b620019309150853d811162001937575b62001927818362000116565b810190620005c9565b38620012b5565b503d6200191b565b620002da565b6200196b915060203d811162001972575b62001962818362000116565b81019062000440565b38620011b9565b503d62001956565b620002da565b620019a6915060203d8111620019ad575b6200199d818362000116565b810190620003e6565b3862001164565b503d62001991565b620002da565b620019e1915060203d8111620019e8575b620019d8818362000116565b8101906200038c565b386200110f565b503d620019cc565b620002da565b62001a1c915060203d811162001a23575b62001a13818362000116565b810190620002b1565b38620010b5565b503d62001a07565b620002da565b62001a3d600162000662565b90565b9062001a4f60001991620002ed565b9181191691161790565b9062001a7362001a6d62001a7b926200076c565b6200078e565b825462001a40565b9055565b62001a8962001aa1565b62001a9f62001a9762001a31565b600162001a59565b565b62001ab562001aaf62001df1565b62001e69565b565b62001ad862001ad162001acb6000620006c3565b6200016a565b916200016a565b1462001ae057565b62001aea620000eb565b63d92e233d60e01b81528062001b0360048201620002d4565b0390fd5b600162001b15910162000503565b90565b151590565b62001b288162001b18565b0362001b3057565b600080fd5b9050519062001b448262001b1d565b565b9060208282031262001b635762001b609160000162001b35565b90565b6200015a565b62001b74906200016a565b9052565b62001b839062000503565b9052565b91602062001bad92949362001ba56040820196600083019062001b69565b019062001b78565b565b62001bba81620009de565b9262001bc5620007b9565b5b8062001bdd62001bd68762000503565b9162000503565b101562001cf85762001c0562001bff62001bf9858490620009e2565b62000a16565b62000a25565b602063095ea7b39162001c2e62001c2862001c2289879062000606565b62000684565b62000693565b9062001c53600080199562001c5f62001c46620000eb565b9788968795869462000274565b84526004840162001b87565b03925af1801562001cf25762001c809160009162001cbd575b501562001b18565b62001c965762001c909062001b07565b62001bc6565b62001ca0620000eb565b633e3f8f7360e01b81528062001cb960048201620002d4565b0390fd5b62001ce3915060203d811162001cea575b62001cda818362000116565b81019062001b46565b3862001c78565b503d62001cce565b620002da565b509250505062001d1362001d0d6080620004a9565b620004b8565b602063095ea7b39162001d3162001d2b60c0620004e3565b620004f2565b9062001d56600080199562001d6262001d49620000eb565b9788968795869462000274565b84526004840162001b87565b03925af1801562001de65762001d839160009162001db1575b501562001b18565b62001d8a57565b62001d94620000eb565b633e3f8f7360e01b81528062001dad60048201620002d4565b0390fd5b62001dd7915060203d811162001dde575b62001dce818362000116565b81019062001b46565b3862001d7b565b503d62001dc2565b620002da565b600090565b62001dfb62001dec565b503390565b60018060a01b031690565b62001e1a62001e209162000463565b62001e00565b90565b62001e2f905462001e0b565b90565b62001e3d9062000258565b90565b90565b9062001e5d62001e5762001e659262001e32565b62001e40565b8254620002f3565b9055565b62001e75600062001e23565b62001e8282600062001e43565b9062001eba62001eb37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09362001e32565b9162001e32565b9162001ec5620000eb565b8062001ed181620002d4565b0390a356fe60806040526004361015610013575b610ffd565b61001e6000356101fd565b80630e23d25c146101f8578063239c70ae146101f357806335f0bbd7146101ee57806340695363146101e95780634fee1290146101e457806361d027b3146101df57806363b0e66a146101da578063643aadb7146101d557806364de1e85146101d0578063715018a6146101cb5780637e9845f5146101c657806387674f33146101c15780638da5cb5b146101bc57806395799388146101b757806396df10c0146101b2578063a80dcfee146101ad578063b131da40146101a8578063b67c25a3146101a3578063bf1ad7e01461019e578063cbcb317114610199578063ce6df2b914610194578063d62f3b1c1461018f578063dd418ae21461018a578063ec4d801914610185578063ed987a0814610180578063efeb5f1f1461017b578063f2fde38b14610176578063f810de6714610171578063fc399c791461016c5763febf25bc0361000e57610fca565b610f95565b610f62565b610dfa565b610dc7565b610d92565b610c98565b610c10565b610b7e565b610b4a565b610b15565b610ae0565b610a74565b610a2f565b6109ea565b610934565b6108ad565b610878565b610842565b61080d565b6107a1565b61076c565b6106d3565b6105a4565b6104fb565b610481565b61044c565b610398565b610311565b610284565b60e01c90565b60405190565b600080fd5b600080fd5b600080fd5b60018060a01b031690565b61022c90610218565b90565b61023890610223565b90565b6102448161022f565b0361024b57565b600080fd5b9050359061025d8261023b565b565b906020828203126102795761027691600001610250565b90565b61020e565b60000190565b346102b25761029c61029736600461025f565b611474565b6102a4610203565b806102ae8161027e565b0390f35b610209565b60009103126102c257565b61020e565b7f000000000000000000000000000000000000000000000000000000000000000090565b90565b6102f7906102eb565b9052565b919061030f906000602085019401906102ee565b565b34610341576103213660046102b7565b61033d61032c6102c7565b610334610203565b918291826102fb565b0390f35b610209565b61034f816102eb565b0361035657565b600080fd5b9050359061036882610346565b565b919060408382031261039357806103876103909260008601610250565b9360200161035b565b90565b61020e565b346103c9576103c56103b46103ae36600461036a565b90611602565b6103bc610203565b918291826102fb565b0390f35b610209565b7f000000000000000000000000000000000000000000000000000000000000000090565b90565b61040961040461040e92610218565b6103f2565b610218565b90565b61041a906103f5565b90565b61042690610411565b90565b6104329061041d565b9052565b919061044a90600060208501940190610429565b565b3461047c5761045c3660046102b7565b6104786104676103ce565b61046f610203565b91829182610436565b0390f35b610209565b346104af576104913660046102b7565b6104996121b7565b6104a1610203565b806104ab8161027e565b0390f35b610209565b7f000000000000000000000000000000000000000000000000000000000000000090565b6104e190610223565b9052565b91906104f9906000602085019401906104d8565b565b3461052b5761050b3660046102b7565b6105276105166104b4565b61051e610203565b918291826104e5565b0390f35b610209565b1c90565b60018060a01b031690565b61054f9060086105549302610530565b610534565b90565b90610562915461053f565b90565b6105726002600090610557565b90565b61057e90610411565b90565b61058a90610575565b9052565b91906105a290600060208501940190610581565b565b346105d4576105b43660046102b7565b6105d06105bf610565565b6105c7610203565b9182918261058e565b0390f35b610209565b906020828203126105f3576105f09160000161035b565b90565b61020e565b634e487b7160e01b600052603260045260246000fd5b5490565b600052602060002090565b6106268161060e565b82101561064157610638600191610612565b91020190600090565b6105f8565b60018060a01b031690565b6106619060086106669302610530565b610646565b90565b906106749154610651565b90565b60036106828161060e565b82101561069f5761069c916106969161061d565b90610669565b90565b600080fd5b6106ad90610411565b90565b6106b9906106a4565b9052565b91906106d1906000602085019401906106b0565b565b34610703576106ff6106ee6106e93660046105d9565b610677565b6106f6610203565b918291826106bd565b0390f35b610209565b60ff1690565b61071e9060086107239302610530565b610708565b90565b90610731915461070e565b90565b6107416011600090610726565b90565b151590565b61075290610744565b9052565b919061076a90600060208501940190610749565b565b3461079c5761077c3660046102b7565b610798610787610734565b61078f610203565b91829182610756565b0390f35b610209565b346107cf576107b13660046102b7565b6107b961220f565b6107c1610203565b806107cb8161027e565b0390f35b610209565b90565b6107e79060086107ec9302610530565b6107d4565b90565b906107fa91546107d7565b90565b61080a60106000906107ef565b90565b3461083d5761081d3660046102b7565b6108396108286107fd565b610830610203565b918291826102fb565b0390f35b610209565b346108735761086f61085e61085836600461036a565b90612219565b610866610203565b918291826102fb565b0390f35b610209565b346108a8576108883660046102b7565b6108a461089361287c565b61089b610203565b918291826104e5565b0390f35b610209565b346108dc576108c66108c036600461036a565b9061294b565b6108ce610203565b806108d88161027e565b0390f35b610209565b7f000000000000000000000000000000000000000000000000000000000000000090565b61090e90610411565b90565b61091a90610905565b9052565b919061093290600060208501940190610911565b565b34610964576109443660046102b7565b61096061094f6108e1565b610957610203565b9182918261091e565b0390f35b610209565b61097281610223565b0361097957565b600080fd5b9050359061098b82610969565b565b906020828203126109a7576109a49160000161097e565b90565b61020e565b6109b590610411565b90565b906109c2906109ac565b600052602052604060002090565b6109e7906109e26012916000926109b8565b610726565b90565b34610a1a57610a16610a05610a0036600461098d565b6109d0565b610a0d610203565b91829182610756565b0390f35b610209565b610a2c600f6000906107ef565b90565b34610a5f57610a3f3660046102b7565b610a5b610a4a610a1f565b610a52610203565b918291826102fb565b0390f35b610209565b610a716011600190610726565b90565b34610aa457610a843660046102b7565b610aa0610a8f610a64565b610a97610203565b91829182610756565b0390f35b610209565b90565b610ac0610abb610ac592610aa9565b6103f2565b6102eb565b90565b610ad2600a610aac565b90565b610add610ac8565b90565b34610b1057610af03660046102b7565b610b0c610afb610ad5565b610b03610203565b918291826102fb565b0390f35b610209565b34610b4557610b253660046102b7565b610b41610b30612957565b610b38610203565b918291826102fb565b0390f35b610209565b34610b7957610b63610b5d36600461036a565b90612a73565b610b6b610203565b80610b758161027e565b0390f35b610209565b34610bac57610b8e3660046102b7565b610b96612b43565b610b9e610203565b80610ba88161027e565b0390f35b610209565b50600a90565b90565b610bc381610bb1565b821015610bde57610bd5600191610bb7565b91020190600090565b6105f8565b6005610bee81610bb1565b821015610c0b57610c0891610c0291610bba565b906107ef565b90565b600080fd5b34610c4057610c3c610c2b610c263660046105d9565b610be3565b610c33610203565b918291826102fb565b0390f35b610209565b7f000000000000000000000000000000000000000000000000000000000000000090565b610c7290610411565b90565b610c7e90610c69565b9052565b9190610c9690600060208501940190610c75565b565b34610cc857610ca83660046102b7565b610cc4610cb3610c45565b610cbb610203565b91829182610c82565b0390f35b610209565b5490565b600052602060002090565b610ce581610ccd565b821015610d0057610cf7600191610cd1565b91020190600090565b6105f8565b60018060a01b031690565b610d20906008610d259302610530565b610d05565b90565b90610d339154610d10565b90565b6004610d4181610ccd565b821015610d5e57610d5b91610d5591610cdc565b90610d28565b90565b600080fd5b610d6c90610411565b90565b610d7890610d63565b9052565b9190610d9090600060208501940190610d6f565b565b34610dc257610dbe610dad610da83660046105d9565b610d36565b610db5610203565b91829182610d7c565b0390f35b610209565b34610df557610ddf610dda36600461098d565b612bb8565b610de7610203565b80610df18161027e565b0390f35b610209565b34610e2857610e12610e0d36600461098d565b612c31565b610e1a610203565b80610e248161027e565b0390f35b610209565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b90610e5c90610e32565b810190811067ffffffffffffffff821117610e7657604052565b610e3c565b90610e8e610e87610203565b9283610e52565b565b67ffffffffffffffff8111610ea85760208091020190565b610e3c565b600080fd5b90929192610ec7610ec282610e90565b610e7b565b9381855260208086019202830192818411610f0457915b838310610eeb5750505050565b60208091610ef9848661097e565b815201920191610ede565b610ead565b9080601f83011215610f2757816020610f2493359101610eb2565b90565b610e2d565b90602082820312610f5d57600082013567ffffffffffffffff8111610f5857610f559201610f09565b90565b610213565b61020e565b34610f9057610f7a610f75366004610f2c565b612d3c565b610f82610203565b80610f8c8161027e565b0390f35b610209565b34610fc557610fc1610fb0610fab36600461098d565b612d4c565b610fb8610203565b91829182610756565b0390f35b610209565b34610ff857610fda3660046102b7565b610fe2612d8f565b610fea610203565b80610ff48161027e565b0390f35b610209565b600080fd5b6110139061100e612e1b565b6111c8565b61101b612e87565b565b60081c90565b61102f6110349161101d565b610708565b90565b6110419054611023565b90565b600080fd5b60e01b90565b9050519061105c82610346565b565b90602082820312611078576110759160000161104f565b90565b61020e565b611085610203565b3d6000823e3d90fd5b90565b6110a56110a06110aa9261108e565b6103f2565b6102eb565b90565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6110e56110eb916102eb565b916102eb565b9081156110f6570490565b6110ad565b60ff1690565b61110a816110fb565b0361111157565b600080fd5b9050519061112382611101565b565b9060208282031261113f5761113c91600001611116565b90565b61020e565b611150611156916110fb565b916110fb565b90039060ff821161116357565b6110c3565b611171906110fb565b604d811161117f57600a0a90565b6110c3565b90565b61119b6111966111a092611184565b6103f2565b6102eb565b90565b6111b26111b8919392936102eb565b926102eb565b82039182116111c357565b6110c3565b6111db6111d56011611037565b15610744565b611451576111e7612957565b61122b60206112157f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb0190611223610203565b938492611049565b8252818061123b6004820161027e565b03915afa801561144c5761126961126e916112749360009161141e575b506112636064611091565b906110d9565b6102eb565b916102eb565b10156113fb576112bf9060206112a97f0000000000000000000000000000000000000000000000000000000000000000610c69565b63313ce567906112b7610203565b948592611049565b825281806112cf6004820161027e565b03915afa80156113f657611307926000916113c8575b5060206112f1836106a4565b63313ce567906112ff610203565b958692611049565b825281806113176004820161027e565b03915afa9081156113c35761133f61138b926113449261139196600092611393575b50611144565b611168565b61138661134f612957565b61138061137a60056113746113646005610bb1565b61136e6001611187565b906111a3565b90610bba565b906107ef565b906110d9565b6110d9565b90612f5f565b565b6113b591925060203d81116113bc575b6113ad8183610e52565b810190611125565b9038611339565b503d6113a3565b61107d565b6113e9915060203d81116113ef575b6113e18183610e52565b810190611125565b386112e5565b503d6113d7565b61107d565b611403610203565b63e802952160e01b81528061141a6004820161027e565b0390fd5b61143f915060203d8111611445575b6114378183610e52565b81019061105e565b38611258565b503d61142d565b61107d565b611459610203565b63914edb0f60e01b8152806114706004820161027e565b0390fd5b61147d90611002565b565b600090565b61148e600a610aac565b90565b67ffffffffffffffff81116114a65760200290565b610e3c565b6114b76114bc91611491565b610e7b565b90565b369037565b906114e26114d1836114ab565b926114dc8491611491565b906114bf565b565b6114ee600a6114c4565b90565b90565b61150861150361150d926114f1565b6103f2565b6102eb565b90565b9061151a906102eb565b9052565b600161152a91016102eb565b90565b50600a90565b9061153d8261152d565b81101561154b576020020190565b6105f8565b91602061157292949361156b604082019660008301906102ee565b01906102ee565b565b60001c90565b61158661158b91611574565b6107d4565b90565b611598905461157a565b90565b6115aa6115b0919392936102eb565b926102eb565b82018092116115bb57565b6110c3565b6115cf6115d5919392936102eb565b926102eb565b916115e18382026102eb565b9281840414901517156115f057565b6110c3565b6115ff90516102eb565b90565b91909161160d61147f565b506116166114e4565b90611621600a6114ab565b61163761162e60006114f4565b60008301611510565b61164d61164460006114f4565b60208301611510565b61166361165a60006114f4565b60408301611510565b61167961167060006114f4565b60608301611510565b61168f61168660006114f4565b60808301611510565b6116a561169c60006114f4565b60a08301611510565b6116bb6116b260006114f4565b60c08301611510565b6116d16116c860006114f4565b60e08301611510565b6116e86116de60006114f4565b6101008301611510565b6116ff6116f560006114f4565b6101208301611510565b9260009061175261171060006114f4565b93602061173c7f0000000000000000000000000000000000000000000000000000000000000000610c69565b63313ce5679061174a610203565b948592611049565b825281806117626004820161027e565b03915afa9182156120bf57600092612085575b50602061178461179a926106a4565b63313ce56790611792610203565b938492611049565b825281806117aa6004820161027e565b03915afa8015612080576117cf926117ca92600092612050575b50611144565b611168565b926117d861147f565b5b806117f36117ed6117e8611484565b6102eb565b916102eb565b1015611b835761183d60206118277f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb0190611835610203565b938492611049565b8252818061184d6004820161027e565b03915afa908115611b7e576118899161187791600091611b50575b50611871611484565b906110d9565b6118848891849092611533565b611510565b6118cd60206118b77f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb01906118c5610203565b938492611049565b825281806118dd6004820161027e565b03915afa8015611b4b576119096119249161192b93600091611b1d575b50611903611484565b906110d9565b61191e61191860058690610bba565b906107ef565b906110d9565b86906110d9565b8061193f61193960006114f4565b916102eb565b1480611a56575b61196e57906119646119699261195f8a91849092611533565b611510565b61151e565b6117d9565b506119b3602061199d7f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb01906119ab610203565b938492611049565b825281806119c36004820161027e565b03915afa8015611a51576119ef6119f7916119fd93600091611a23575b506119e9611484565b906110d9565b926005610bba565b906107ef565b90611a1f611a09610203565b92839263d379876360e01b845260048401611550565b0390fd5b611a44915060203d8111611a4a575b611a3c8183610e52565b81019061105e565b856119e0565b503d611a32565b61107d565b50611a9b6020611a857f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb0190611a93610203565b938492611049565b82528180611aab6004820161027e565b03915afa8015611b1857611ad091600091611aea575b50611aca611484565b906110d9565b611ae3611add60006114f4565b916102eb565b1415611946565b611b0b915060203d8111611b11575b611b038183610e52565b81019061105e565b38611ac1565b503d611af9565b61107d565b611b3e915060203d8111611b44575b611b368183610e52565b81019061105e565b386118fa565b503d611b2c565b61107d565b611b71915060203d8111611b77575b611b698183610e52565b81019061105e565b38611868565b503d611b5f565b61107d565b509395919094611b9161147f565b965b87611bad611ba7611ba2611484565b6102eb565b916102eb565b101561204357611bbd600f61158e565b611c06611c00611bfb611bed611bdd8d611bd76001611187565b9061159b565b611be76064611091565b906115c0565b611bf5611484565b906110d9565b6102eb565b916102eb565b1060001461203557611c526020611c3c7f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb0190611c4a610203565b938492611049565b82528180611c626004820161027e565b03915afa90811561203057611cac611c92611cce93611cbc93600091612002575b50611c8c611484565b906110d9565b611ca68c611ca06001611187565b9061159b565b906115c0565b611cb6601061158e565b906111a3565b611cc983918b9092611533565b611510565b611cd88315610744565b611f0c575b83611d02611cfc611cf7611cf2868d90611533565b6115f5565b6102eb565b916102eb565b1115600014611df257505050611d5f611d3a611d3383611d2d611d2760058b90610bba565b906107ef565b906115c0565b84906115c0565b92611d5a84611d54611d4e60058b90610bba565b906107ef565b906110d9565b6110d9565b611d71611d6b836102eb565b916102eb565b03611db85750611d839293509061159b565b5b80611d9e611d98611d93612957565b6102eb565b916102eb565b11600014611db35750611daf612957565b5b90565b611db0565b611dcc611dc6866005610bba565b906107ef565b90611dee611dd8610203565b9283926368bb8cbb60e01b845260048401611550565b0390fd5b9091969294611e32611e2b611e10611e0b868890611533565b6115f5565b611e25611e1f60058990610bba565b906107ef565b906115c0565b86906115c0565b611e5b611e5482611e4e611e4860058a90610bba565b906107ef565b906110d9565b87906110d9565b611e7f611e79611e74611e6f888a90611533565b6115f5565b6102eb565b916102eb565b03611ebe57611e95611eb692611eaf929061159b565b96611ea9611ea4868890611533565b6115f5565b906111a3565b935b61151e565b969190611b93565b84611ee6611ee0611ed8611ed3888590611533565b6115f5565b926005610bba565b906107ef565b90611f08611ef2610203565b9283926368bb8cbb60e01b845260048401611550565b0390fd5b9150611f49611f42611f27611f22858b90611533565b6115f5565b611f3c611f3660058c90610bba565b906107ef565b906110d9565b85906110d9565b80611f5d611f5760006114f4565b916102eb565b1480611fd4575b611f8657611f7e90611f7983918a9092611533565b611510565b600191611cdd565b87611fae611fa8611fa0611f9b878590611533565b6115f5565b926005610bba565b906107ef565b90611fd0611fba610203565b92839263d379876360e01b845260048401611550565b0390fd5b50611fe8611fe3848a90611533565b6115f5565b611ffb611ff560006114f4565b916102eb565b1415611f64565b612023915060203d8111612029575b61201b8183610e52565b81019061105e565b38611c83565b503d612011565b61107d565b909150611eb6600097611eb1565b5050505050909150611d84565b61207291925060203d8111612079575b61206a8183610e52565b810190611125565b90386117c4565b503d612060565b61107d565b61179a9192506117846120af602092833d81116120b8575b6120a78183610e52565b810190611125565b93925050611775565b503d61209d565b61107d565b6120cc613555565b6120d4612142565b565b6120e26120e791611574565b610708565b90565b6120f490546120d6565b90565b60001b90565b9061210960ff916120f7565b9181191691161790565b61211c90610744565b90565b90565b9061213761213261213e92612113565b61211f565b82546120fd565b9055565b61214c60116120ea565b6121945761215c60016011612122565b7f80c8f4ee93129ab9b38a5d893cc03b09e1639b21d4adcda0881f1344acbe5fb9612185610203565b8061218f8161027e565b0390a1565b61219c610203565b6376c855ed60e01b8152806121b36004820161027e565b0390fd5b6121bf6120c4565b565b6121c9613555565b6121d16121fb565b565b6121e76121e26121ec926114f1565b6103f2565b610218565b90565b6121f8906121d3565b90565b61220d61220860006121ef565b6135e8565b565b6122176121c1565b565b61222161147f565b5061222c600a6114ab565b61224261223960006114f4565b60008301611510565b61225861224f60006114f4565b60208301611510565b61226e61226560006114f4565b60408301611510565b61228461227b60006114f4565b60608301611510565b61229a61229160006114f4565b60808301611510565b6122b06122a760006114f4565b60a08301611510565b6122c66122bd60006114f4565b60c08301611510565b6122dc6122d360006114f4565b60e08301611510565b6122f36122e960006114f4565b6101008301611510565b61230a61230060006114f4565b6101208301611510565b60009161235c61231a60006114f4565b9160206123467f0000000000000000000000000000000000000000000000000000000000000000610c69565b63313ce56790612354610203565b948592611049565b8252818061236c6004820161027e565b03915afa9182156128465760009261280c575b50602061238e6123a4926106a4565b63313ce5679061239c610203565b938492611049565b825281806123b46004820161027e565b03915afa8015612807576123d9926123d4926000926127d7575b50611144565b611168565b926123e261147f565b5b806123fd6123f76123f2611484565b6102eb565b916102eb565b10156124fb576124489060206124327f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb0190612440610203565b948592611049565b825281806124586004820161027e565b03915afa80156124f6576124ac6124a561248a6124be936124c3966000916124c8575b50612484611484565b906110d9565b61249f61249960058790610bba565b906107ef565b906110d9565b88906110d9565b6124b98791849092611533565b611510565b61151e565b6123e3565b6124e9915060203d81116124ef575b6124e18183610e52565b81019061105e565b3861247b565b503d6124d7565b61107d565b5093909392919261250a61147f565b935b8461252661252061251b611484565b6102eb565b916102eb565b10156127cd57612536600f61158e565b61257f6125796125746125666125568a6125506001611187565b9061159b565b6125606064611091565b906115c0565b61256e611484565b906110d9565b6102eb565b916102eb565b106000146127c0576125918215610744565b61269b575b826125e36125dd6125d86125d16125b66125b1878c90611533565b6115f5565b6125cb6125c560058d90610bba565b906107ef565b906115c0565b88906115c0565b6102eb565b916102eb565b11156000146126245750509161261461261a9261260f6126096126209796946005610bba565b906107ef565b6115c0565b906110d9565b9061159b565b5b90565b9093919461268d61264b61269492612645612640868890611533565b6115f5565b9061159b565b96612687612680612665612660878990611533565b6115f5565b61267a61267460058a90610bba565b906107ef565b906115c0565b87906115c0565b906111a3565b925b61151e565b939061250c565b90506126e160206126cb7f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb01906126d9610203565b938492611049565b825281806126f16004820161027e565b03915afa9081156127bb5761276c612751612741612727612785956127739560009161278d575b50612721611484565b906110d9565b61273b8a6127356001611187565b9061159b565b906115c0565b61274b601061158e565b906111a3565b61276661276060058a90610bba565b906107ef565b906110d9565b85906110d9565b6127808391879092611533565b611510565b600190612596565b6127ae915060203d81116127b4575b6127a68183610e52565b81019061105e565b38612718565b503d61279c565b61107d565b905061269460009461268f565b5050505050612621565b6127f991925060203d8111612800575b6127f18183610e52565b810190611125565b90386123ce565b503d6127e7565b61107d565b6123a491925061238e612836602092833d811161283f575b61282e8183610e52565b810190611125565b9392505061237f565b503d612824565b61107d565b600090565b60018060a01b031690565b61286761286c91611574565b612850565b90565b612879905461285b565b90565b61288461284b565b5061288f600061286f565b90565b906128a49161289f612e1b565b6128ae565b6128ac612e87565b565b906128d36128cd6128c860126128c2613649565b906109b8565b6120ea565b15610744565b6128e2576128e091612905565b565b6128ea610203565b6322f8556360e01b8152806129016004820161027e565b0390fd5b9061291961291360116120ea565b15610744565b6129285761292691612f5f565b565b612930610203565b63914edb0f60e01b8152806129476004820161027e565b0390fd5b9061295591612892565b565b61295f61147f565b506129a4602061298e7f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb019061299c610203565b938492611049565b825281806129b46004820161027e565b03915afa8015612a0c576129db916000916129de575b506129d5601061158e565b906111a3565b90565b6129ff915060203d8111612a05575b6129f78183610e52565b81019061105e565b386129ca565b503d6129ed565b61107d565b90612a2391612a1e612e1b565b612a2d565b612a2b612e87565b565b90612a41612a3b6011611037565b15610744565b612a5057612a4e91612f5f565b565b612a58610203565b63914edb0f60e01b815280612a6f6004820161027e565b0390fd5b90612a7d91612a11565b565b612a87613555565b612a8f612ace565b565b60081b90565b90612aa461ff0091612a91565b9181191691161790565b90612ac3612abe612aca92612113565b61211f565b8254612a97565b9055565b612ad86011611037565b612b2057612ae860016011612aae565b7fbad7871e16f9b9d8b2a6bd6e38ada7c99940913046fe099cffa0040643fb064e612b11610203565b80612b1b8161027e565b0390a1565b612b28610203565b6376c855ed60e01b815280612b3f6004820161027e565b0390fd5b612b4b612a7f565b565b612b5e90612b59613555565b612b60565b565b612b766001612b71601284906109b8565b612122565b612ba07f12c94d2725e3b811140fad6a73350adbd38646149c9a9a62ffc1018bec2ec97c916109ac565b90612ba9610203565b80612bb38161027e565b0390a2565b612bc190612b4d565b565b612bd490612bcf613555565b612bd6565b565b80612bf2612bec612be760006121ef565b610223565b91610223565b14612c0257612c00906135e8565b565b612c2d612c0f60006121ef565b612c17610203565b91829163b20f76e360e01b8352600483016104e5565b0390fd5b612c3a90612bc3565b565b612c4d90612c48613555565b612c80565b565b5190565b90612c5d82612c4f565b811015612c6e576020809102010190565b6105f8565b612c7d9051610223565b90565b90612c8a82612c4f565b90612c9361147f565b5b80612ca7612ca1856102eb565b916102eb565b1015612d3657612d3190612cd96001612cd46012612cce612cc98a8790612c53565b612c73565b906109b8565b612122565b612cec612ce7868390612c53565b612c73565b612d167f12c94d2725e3b811140fad6a73350adbd38646149c9a9a62ffc1018bec2ec97c916109ac565b90612d1f610203565b80612d298161027e565b0390a261151e565b612c94565b50915050565b612d4590612c3c565b565b600090565b612d63612d6891612d5b612d47565b5060126109b8565b6120ea565b90565b612d73612e1b565b612d7b612d85565b612d83612e87565b565b612d8d613656565b565b612d97612d6b565b565b90565b612db0612dab612db592612d99565b6103f2565b6102eb565b90565b612dc26002612d9c565b90565b90612dd2600019916120f7565b9181191691161790565b612df0612deb612df5926102eb565b6103f2565b6102eb565b90565b90565b90612e10612e0b612e1792612ddc565b612df8565b8254612dc5565b9055565b612e25600161158e565b612e3e612e38612e33612db8565b6102eb565b916102eb565b14612e5757612e55612e4e612db8565b6001612dfb565b565b612e5f610203565b6306fda65d60e31b815280612e766004820161027e565b0390fd5b612e846001611187565b90565b612e99612e92612e7a565b6001612dfb565b565b612ea4906103f5565b90565b612eb090612e9b565b90565b612ebc90610411565b90565b612ec8906103f5565b90565b612ed490612ebf565b90565b6000910312612ee257565b61020e565b916020612f09929493612f02604082019660008301906104d8565b01906102ee565b565b612f17612f1c91611574565b610534565b90565b612f299054612f0b565b90565b604090612f56612f5d9496959396612f4c60608401986000850190610d6f565b60208301906104d8565b01906102ee565b565b90612f72612f6c836137af565b15610744565b61353257612f81828290611602565b9081612f96612f9060006114f4565b916102eb565b148015613511575b80156134d7575b6134b457613060612fe4612fd483612fce6064612fc9612fc3610ac8565b91611091565b6111a3565b906115c0565b612fde6064611091565b906110d9565b91613002612ffb85612ff6601061158e565b61159b565b6010612dfb565b61301f61300f601061158e565b6130196064611091565b906115c0565b602061304a7f0000000000000000000000000000000000000000000000000000000000000000610c69565b63d5abeb0190613058610203565b958692611049565b825281806130706004820161027e565b03915afa9283156134af576130c69361309c926130959260009261347f575b506110d9565b600f612dfb565b6130ad6130a8866106a4565b612ea7565b906130b6613649565b6130bf30612eb3565b91926138a4565b6130ff6130fa6130f57f0000000000000000000000000000000000000000000000000000000000000000610c69565b612ecb565b610c69565b63af14052c90803b1561347a576131239160009161311b610203565b938492611049565b82528183816131346004820161027e565b03925af1801561347557613448575b5061317d6131786131737f0000000000000000000000000000000000000000000000000000000000000000610c69565b612ecb565b610c69565b6340c10f1961318a613649565b8492803b15613443576131b1600080946131bc6131a5610203565b97889687958694611049565b845260048401612ee7565b03925af1801561343e57613411575b506131d6600361060e565b926131df61147f565b5b806131f36131ed876102eb565b916102eb565b1015613403578161322061321a61321561320f6003869061061d565b90610669565b61022f565b9161022f565b146132335761322e9061151e565b6131e0565b909192935061324a6132456002612f1f565b610575565b61326361325d638eda7e69936004610cdc565b90610d28565b9061326d30612eb3565b9492813b156133fe576000613295916132a08296613289610203565b998a9788968795611049565b855260048501612f2c565b03925af19182156133f957613326926133cc575b505b6132c76132c2826106a4565b612ea7565b9060206132f47f0000000000000000000000000000000000000000000000000000000000000000926106a4565b6370a082319061331b61330630612eb3565b9261330f610203565b97889485938493611049565b8352600483016104e5565b03915afa9182156133c75761334393600093613397575b506138f4565b61334b613656565b613353613649565b6133926133807f3f2c9d57c068687834f0de942a9babb9e5acab57d516d3480a3c16ee165a4273926109ac565b92613389610203565b918291826102fb565b0390a2565b6133b991935060203d81116133c0575b6133b18183610e52565b81019061105e565b913861333d565b503d6133a7565b61107d565b6133ec9060003d81116133f2575b6133e48183610e52565b810190612ed7565b386132b4565b503d6133da565b61107d565b611044565b5090506133269192506132b6565b6134319060003d8111613437575b6134298183610e52565b810190612ed7565b386131cb565b503d61341f565b61107d565b611044565b6134689060003d811161346e575b6134608183610e52565b810190612ed7565b38613143565b503d613456565b61107d565b611044565b6134a191925060203d81116134a8575b6134998183610e52565b81019061105e565b903861308f565b503d61348f565b61107d565b6134bc610203565b63199f5a0360e31b8152806134d36004820161027e565b0390fd5b508161350b6135057f00000000000000000000000000000000000000000000000000000000000000006102eb565b916102eb565b11612fa5565b508161352c613526613521612957565b6102eb565b916102eb565b11612f9e565b61353a610203565b635bfbc03960e01b8152806135516004820161027e565b0390fd5b61355d61287c565b61357661357061356b613649565b610223565b91610223565b0361357d57565b6135a6613588613649565b613590610203565b9182916332b2baa360e01b8352600483016104e5565b0390fd5b906135bb60018060a01b03916120f7565b9181191691161790565b90565b906135dd6135d86135e4926109ac565b6135c5565b82546135aa565b9055565b6135f2600061286f565b6135fd8260006135c8565b9061363161362b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936109ac565b916109ac565b9161363a610203565b806136448161027e565b0390a3565b61365161284b565b503390565b6136b660206136847f0000000000000000000000000000000000000000000000000000000000000000610905565b6370a08231906136ab61369630612eb3565b9261369f610203565b95869485938493611049565b8352600483016104e5565b03915afa9081156137aa5760009161377c575b50806136de6136d860006114f4565b916102eb565b116136e7575b50565b6136f96136f46002612f1f565b610575565b9063dc7d732390823b1561377757613731926137266000809461371a610203565b96879586948593611049565b8352600483016102fb565b03925af1801561377257613745575b6136e4565b6137659060003d811161376b575b61375d8183610e52565b810190612ed7565b38613740565b503d613753565b61107d565b611044565b61379d915060203d81116137a3575b6137958183610e52565b81019061105e565b386136c9565b503d61378b565b61107d565b6137b7612d47565b506137c2600361060e565b9060006137cd61147f565b5b806137e16137db866102eb565b916102eb565b101561382b578261380e6138086138036137fd6003869061061d565b90610669565b61022f565b9161022f565b146138215761381c9061151e565b6137ce565b5050505060015b90565b50915050613828565b61383d90610411565b90565b63ffffffff1690565b63ffffffff60e01b1690565b61386961386461386e92613840565b611049565b613849565b90565b60409061389b6138a29496959396613891606084019860008501906104d8565b60208301906104d8565b01906102ee565b565b6004926138de6138f295936138ed93946138c56323b872dd92949192613855565b936138ce610203565b9788956020870190815201613871565b60208201810382520383610e52565b613942565b565b9061393b6139409361392c6004949361391363a9059cbb919391613855565b9261391c610203565b9687946020860190815201612ee7565b60208201810382520383610e52565b613942565b565b90600060209161395061147f565b5061395961147f565b50828151910182855af1156139f7573d6000519061398061397a60006114f4565b916102eb565b146000146139dd575061399281613834565b3b6139a66139a060006114f4565b916102eb565b145b6139af5750565b6139bb6139d991613834565b6139c3610203565b918291635274afe760e01b8352600483016104e5565b0390fd5b6139f06139ea6001611187565b916102eb565b14156139a8565b6040513d6000823e3d90fdfea264697066735822122041e1d3d8d8580d0e9626cb8d271bb21b508138507076d840eb4db751942ef1c064736f6c634300081800330000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c00000000000000000000000012684d18bdba8e31936f40abce1175366874114f
Deployed Bytecode
0x60806040526004361015610013575b610ffd565b61001e6000356101fd565b80630e23d25c146101f8578063239c70ae146101f357806335f0bbd7146101ee57806340695363146101e95780634fee1290146101e457806361d027b3146101df57806363b0e66a146101da578063643aadb7146101d557806364de1e85146101d0578063715018a6146101cb5780637e9845f5146101c657806387674f33146101c15780638da5cb5b146101bc57806395799388146101b757806396df10c0146101b2578063a80dcfee146101ad578063b131da40146101a8578063b67c25a3146101a3578063bf1ad7e01461019e578063cbcb317114610199578063ce6df2b914610194578063d62f3b1c1461018f578063dd418ae21461018a578063ec4d801914610185578063ed987a0814610180578063efeb5f1f1461017b578063f2fde38b14610176578063f810de6714610171578063fc399c791461016c5763febf25bc0361000e57610fca565b610f95565b610f62565b610dfa565b610dc7565b610d92565b610c98565b610c10565b610b7e565b610b4a565b610b15565b610ae0565b610a74565b610a2f565b6109ea565b610934565b6108ad565b610878565b610842565b61080d565b6107a1565b61076c565b6106d3565b6105a4565b6104fb565b610481565b61044c565b610398565b610311565b610284565b60e01c90565b60405190565b600080fd5b600080fd5b600080fd5b60018060a01b031690565b61022c90610218565b90565b61023890610223565b90565b6102448161022f565b0361024b57565b600080fd5b9050359061025d8261023b565b565b906020828203126102795761027691600001610250565b90565b61020e565b60000190565b346102b25761029c61029736600461025f565b611474565b6102a4610203565b806102ae8161027e565b0390f35b610209565b60009103126102c257565b61020e565b7f00000000000000000000000000000000000000000097432b8379da85b0a0000090565b90565b6102f7906102eb565b9052565b919061030f906000602085019401906102ee565b565b34610341576103213660046102b7565b61033d61032c6102c7565b610334610203565b918291826102fb565b0390f35b610209565b61034f816102eb565b0361035657565b600080fd5b9050359061036882610346565b565b919060408382031261039357806103876103909260008601610250565b9360200161035b565b90565b61020e565b346103c9576103c56103b46103ae36600461036a565b90611602565b6103bc610203565b918291826102fb565b0390f35b610209565b7f000000000000000000000000b8c30cf1aa46b4e8ee8d008a0f2f763b3d5bac0e90565b90565b61040961040461040e92610218565b6103f2565b610218565b90565b61041a906103f5565b90565b61042690610411565b90565b6104329061041d565b9052565b919061044a90600060208501940190610429565b565b3461047c5761045c3660046102b7565b6104786104676103ce565b61046f610203565b91829182610436565b0390f35b610209565b346104af576104913660046102b7565b6104996121b7565b6104a1610203565b806104ab8161027e565b0390f35b610209565b7f00000000000000000000000012684d18bdba8e31936f40abce1175366874114f90565b6104e190610223565b9052565b91906104f9906000602085019401906104d8565b565b3461052b5761050b3660046102b7565b6105276105166104b4565b61051e610203565b918291826104e5565b0390f35b610209565b1c90565b60018060a01b031690565b61054f9060086105549302610530565b610534565b90565b90610562915461053f565b90565b6105726002600090610557565b90565b61057e90610411565b90565b61058a90610575565b9052565b91906105a290600060208501940190610581565b565b346105d4576105b43660046102b7565b6105d06105bf610565565b6105c7610203565b9182918261058e565b0390f35b610209565b906020828203126105f3576105f09160000161035b565b90565b61020e565b634e487b7160e01b600052603260045260246000fd5b5490565b600052602060002090565b6106268161060e565b82101561064157610638600191610612565b91020190600090565b6105f8565b60018060a01b031690565b6106619060086106669302610530565b610646565b90565b906106749154610651565b90565b60036106828161060e565b82101561069f5761069c916106969161061d565b90610669565b90565b600080fd5b6106ad90610411565b90565b6106b9906106a4565b9052565b91906106d1906000602085019401906106b0565b565b34610703576106ff6106ee6106e93660046105d9565b610677565b6106f6610203565b918291826106bd565b0390f35b610209565b60ff1690565b61071e9060086107239302610530565b610708565b90565b90610731915461070e565b90565b6107416011600090610726565b90565b151590565b61075290610744565b9052565b919061076a90600060208501940190610749565b565b3461079c5761077c3660046102b7565b610798610787610734565b61078f610203565b91829182610756565b0390f35b610209565b346107cf576107b13660046102b7565b6107b961220f565b6107c1610203565b806107cb8161027e565b0390f35b610209565b90565b6107e79060086107ec9302610530565b6107d4565b90565b906107fa91546107d7565b90565b61080a60106000906107ef565b90565b3461083d5761081d3660046102b7565b6108396108286107fd565b610830610203565b918291826102fb565b0390f35b610209565b346108735761086f61085e61085836600461036a565b90612219565b610866610203565b918291826102fb565b0390f35b610209565b346108a8576108883660046102b7565b6108a461089361287c565b61089b610203565b918291826104e5565b0390f35b610209565b346108dc576108c66108c036600461036a565b9061294b565b6108ce610203565b806108d88161027e565b0390f35b610209565b7f000000000000000000000000e30e73cc52ef50a4e4a8b1a3dd0b002b2276f85490565b61090e90610411565b90565b61091a90610905565b9052565b919061093290600060208501940190610911565b565b34610964576109443660046102b7565b61096061094f6108e1565b610957610203565b9182918261091e565b0390f35b610209565b61097281610223565b0361097957565b600080fd5b9050359061098b82610969565b565b906020828203126109a7576109a49160000161097e565b90565b61020e565b6109b590610411565b90565b906109c2906109ac565b600052602052604060002090565b6109e7906109e26012916000926109b8565b610726565b90565b34610a1a57610a16610a05610a0036600461098d565b6109d0565b610a0d610203565b91829182610756565b0390f35b610209565b610a2c600f6000906107ef565b90565b34610a5f57610a3f3660046102b7565b610a5b610a4a610a1f565b610a52610203565b918291826102fb565b0390f35b610209565b610a716011600190610726565b90565b34610aa457610a843660046102b7565b610aa0610a8f610a64565b610a97610203565b91829182610756565b0390f35b610209565b90565b610ac0610abb610ac592610aa9565b6103f2565b6102eb565b90565b610ad2600a610aac565b90565b610add610ac8565b90565b34610b1057610af03660046102b7565b610b0c610afb610ad5565b610b03610203565b918291826102fb565b0390f35b610209565b34610b4557610b253660046102b7565b610b41610b30612957565b610b38610203565b918291826102fb565b0390f35b610209565b34610b7957610b63610b5d36600461036a565b90612a73565b610b6b610203565b80610b758161027e565b0390f35b610209565b34610bac57610b8e3660046102b7565b610b96612b43565b610b9e610203565b80610ba88161027e565b0390f35b610209565b50600a90565b90565b610bc381610bb1565b821015610bde57610bd5600191610bb7565b91020190600090565b6105f8565b6005610bee81610bb1565b821015610c0b57610c0891610c0291610bba565b906107ef565b90565b600080fd5b34610c4057610c3c610c2b610c263660046105d9565b610be3565b610c33610203565b918291826102fb565b0390f35b610209565b7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea90565b610c7290610411565b90565b610c7e90610c69565b9052565b9190610c9690600060208501940190610c75565b565b34610cc857610ca83660046102b7565b610cc4610cb3610c45565b610cbb610203565b91829182610c82565b0390f35b610209565b5490565b600052602060002090565b610ce581610ccd565b821015610d0057610cf7600191610cd1565b91020190600090565b6105f8565b60018060a01b031690565b610d20906008610d259302610530565b610d05565b90565b90610d339154610d10565b90565b6004610d4181610ccd565b821015610d5e57610d5b91610d5591610cdc565b90610d28565b90565b600080fd5b610d6c90610411565b90565b610d7890610d63565b9052565b9190610d9090600060208501940190610d6f565b565b34610dc257610dbe610dad610da83660046105d9565b610d36565b610db5610203565b91829182610d7c565b0390f35b610209565b34610df557610ddf610dda36600461098d565b612bb8565b610de7610203565b80610df18161027e565b0390f35b610209565b34610e2857610e12610e0d36600461098d565b612c31565b610e1a610203565b80610e248161027e565b0390f35b610209565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b90610e5c90610e32565b810190811067ffffffffffffffff821117610e7657604052565b610e3c565b90610e8e610e87610203565b9283610e52565b565b67ffffffffffffffff8111610ea85760208091020190565b610e3c565b600080fd5b90929192610ec7610ec282610e90565b610e7b565b9381855260208086019202830192818411610f0457915b838310610eeb5750505050565b60208091610ef9848661097e565b815201920191610ede565b610ead565b9080601f83011215610f2757816020610f2493359101610eb2565b90565b610e2d565b90602082820312610f5d57600082013567ffffffffffffffff8111610f5857610f559201610f09565b90565b610213565b61020e565b34610f9057610f7a610f75366004610f2c565b612d3c565b610f82610203565b80610f8c8161027e565b0390f35b610209565b34610fc557610fc1610fb0610fab36600461098d565b612d4c565b610fb8610203565b91829182610756565b0390f35b610209565b34610ff857610fda3660046102b7565b610fe2612d8f565b610fea610203565b80610ff48161027e565b0390f35b610209565b600080fd5b6110139061100e612e1b565b6111c8565b61101b612e87565b565b60081c90565b61102f6110349161101d565b610708565b90565b6110419054611023565b90565b600080fd5b60e01b90565b9050519061105c82610346565b565b90602082820312611078576110759160000161104f565b90565b61020e565b611085610203565b3d6000823e3d90fd5b90565b6110a56110a06110aa9261108e565b6103f2565b6102eb565b90565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6110e56110eb916102eb565b916102eb565b9081156110f6570490565b6110ad565b60ff1690565b61110a816110fb565b0361111157565b600080fd5b9050519061112382611101565b565b9060208282031261113f5761113c91600001611116565b90565b61020e565b611150611156916110fb565b916110fb565b90039060ff821161116357565b6110c3565b611171906110fb565b604d811161117f57600a0a90565b6110c3565b90565b61119b6111966111a092611184565b6103f2565b6102eb565b90565b6111b26111b8919392936102eb565b926102eb565b82039182116111c357565b6110c3565b6111db6111d56011611037565b15610744565b611451576111e7612957565b61122b60206112157f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb0190611223610203565b938492611049565b8252818061123b6004820161027e565b03915afa801561144c5761126961126e916112749360009161141e575b506112636064611091565b906110d9565b6102eb565b916102eb565b10156113fb576112bf9060206112a97f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63313ce567906112b7610203565b948592611049565b825281806112cf6004820161027e565b03915afa80156113f657611307926000916113c8575b5060206112f1836106a4565b63313ce567906112ff610203565b958692611049565b825281806113176004820161027e565b03915afa9081156113c35761133f61138b926113449261139196600092611393575b50611144565b611168565b61138661134f612957565b61138061137a60056113746113646005610bb1565b61136e6001611187565b906111a3565b90610bba565b906107ef565b906110d9565b6110d9565b90612f5f565b565b6113b591925060203d81116113bc575b6113ad8183610e52565b810190611125565b9038611339565b503d6113a3565b61107d565b6113e9915060203d81116113ef575b6113e18183610e52565b810190611125565b386112e5565b503d6113d7565b61107d565b611403610203565b63e802952160e01b81528061141a6004820161027e565b0390fd5b61143f915060203d8111611445575b6114378183610e52565b81019061105e565b38611258565b503d61142d565b61107d565b611459610203565b63914edb0f60e01b8152806114706004820161027e565b0390fd5b61147d90611002565b565b600090565b61148e600a610aac565b90565b67ffffffffffffffff81116114a65760200290565b610e3c565b6114b76114bc91611491565b610e7b565b90565b369037565b906114e26114d1836114ab565b926114dc8491611491565b906114bf565b565b6114ee600a6114c4565b90565b90565b61150861150361150d926114f1565b6103f2565b6102eb565b90565b9061151a906102eb565b9052565b600161152a91016102eb565b90565b50600a90565b9061153d8261152d565b81101561154b576020020190565b6105f8565b91602061157292949361156b604082019660008301906102ee565b01906102ee565b565b60001c90565b61158661158b91611574565b6107d4565b90565b611598905461157a565b90565b6115aa6115b0919392936102eb565b926102eb565b82018092116115bb57565b6110c3565b6115cf6115d5919392936102eb565b926102eb565b916115e18382026102eb565b9281840414901517156115f057565b6110c3565b6115ff90516102eb565b90565b91909161160d61147f565b506116166114e4565b90611621600a6114ab565b61163761162e60006114f4565b60008301611510565b61164d61164460006114f4565b60208301611510565b61166361165a60006114f4565b60408301611510565b61167961167060006114f4565b60608301611510565b61168f61168660006114f4565b60808301611510565b6116a561169c60006114f4565b60a08301611510565b6116bb6116b260006114f4565b60c08301611510565b6116d16116c860006114f4565b60e08301611510565b6116e86116de60006114f4565b6101008301611510565b6116ff6116f560006114f4565b6101208301611510565b9260009061175261171060006114f4565b93602061173c7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63313ce5679061174a610203565b948592611049565b825281806117626004820161027e565b03915afa9182156120bf57600092612085575b50602061178461179a926106a4565b63313ce56790611792610203565b938492611049565b825281806117aa6004820161027e565b03915afa8015612080576117cf926117ca92600092612050575b50611144565b611168565b926117d861147f565b5b806117f36117ed6117e8611484565b6102eb565b916102eb565b1015611b835761183d60206118277f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb0190611835610203565b938492611049565b8252818061184d6004820161027e565b03915afa908115611b7e576118899161187791600091611b50575b50611871611484565b906110d9565b6118848891849092611533565b611510565b6118cd60206118b77f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb01906118c5610203565b938492611049565b825281806118dd6004820161027e565b03915afa8015611b4b576119096119249161192b93600091611b1d575b50611903611484565b906110d9565b61191e61191860058690610bba565b906107ef565b906110d9565b86906110d9565b8061193f61193960006114f4565b916102eb565b1480611a56575b61196e57906119646119699261195f8a91849092611533565b611510565b61151e565b6117d9565b506119b3602061199d7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb01906119ab610203565b938492611049565b825281806119c36004820161027e565b03915afa8015611a51576119ef6119f7916119fd93600091611a23575b506119e9611484565b906110d9565b926005610bba565b906107ef565b90611a1f611a09610203565b92839263d379876360e01b845260048401611550565b0390fd5b611a44915060203d8111611a4a575b611a3c8183610e52565b81019061105e565b856119e0565b503d611a32565b61107d565b50611a9b6020611a857f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb0190611a93610203565b938492611049565b82528180611aab6004820161027e565b03915afa8015611b1857611ad091600091611aea575b50611aca611484565b906110d9565b611ae3611add60006114f4565b916102eb565b1415611946565b611b0b915060203d8111611b11575b611b038183610e52565b81019061105e565b38611ac1565b503d611af9565b61107d565b611b3e915060203d8111611b44575b611b368183610e52565b81019061105e565b386118fa565b503d611b2c565b61107d565b611b71915060203d8111611b77575b611b698183610e52565b81019061105e565b38611868565b503d611b5f565b61107d565b509395919094611b9161147f565b965b87611bad611ba7611ba2611484565b6102eb565b916102eb565b101561204357611bbd600f61158e565b611c06611c00611bfb611bed611bdd8d611bd76001611187565b9061159b565b611be76064611091565b906115c0565b611bf5611484565b906110d9565b6102eb565b916102eb565b1060001461203557611c526020611c3c7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb0190611c4a610203565b938492611049565b82528180611c626004820161027e565b03915afa90811561203057611cac611c92611cce93611cbc93600091612002575b50611c8c611484565b906110d9565b611ca68c611ca06001611187565b9061159b565b906115c0565b611cb6601061158e565b906111a3565b611cc983918b9092611533565b611510565b611cd88315610744565b611f0c575b83611d02611cfc611cf7611cf2868d90611533565b6115f5565b6102eb565b916102eb565b1115600014611df257505050611d5f611d3a611d3383611d2d611d2760058b90610bba565b906107ef565b906115c0565b84906115c0565b92611d5a84611d54611d4e60058b90610bba565b906107ef565b906110d9565b6110d9565b611d71611d6b836102eb565b916102eb565b03611db85750611d839293509061159b565b5b80611d9e611d98611d93612957565b6102eb565b916102eb565b11600014611db35750611daf612957565b5b90565b611db0565b611dcc611dc6866005610bba565b906107ef565b90611dee611dd8610203565b9283926368bb8cbb60e01b845260048401611550565b0390fd5b9091969294611e32611e2b611e10611e0b868890611533565b6115f5565b611e25611e1f60058990610bba565b906107ef565b906115c0565b86906115c0565b611e5b611e5482611e4e611e4860058a90610bba565b906107ef565b906110d9565b87906110d9565b611e7f611e79611e74611e6f888a90611533565b6115f5565b6102eb565b916102eb565b03611ebe57611e95611eb692611eaf929061159b565b96611ea9611ea4868890611533565b6115f5565b906111a3565b935b61151e565b969190611b93565b84611ee6611ee0611ed8611ed3888590611533565b6115f5565b926005610bba565b906107ef565b90611f08611ef2610203565b9283926368bb8cbb60e01b845260048401611550565b0390fd5b9150611f49611f42611f27611f22858b90611533565b6115f5565b611f3c611f3660058c90610bba565b906107ef565b906110d9565b85906110d9565b80611f5d611f5760006114f4565b916102eb565b1480611fd4575b611f8657611f7e90611f7983918a9092611533565b611510565b600191611cdd565b87611fae611fa8611fa0611f9b878590611533565b6115f5565b926005610bba565b906107ef565b90611fd0611fba610203565b92839263d379876360e01b845260048401611550565b0390fd5b50611fe8611fe3848a90611533565b6115f5565b611ffb611ff560006114f4565b916102eb565b1415611f64565b612023915060203d8111612029575b61201b8183610e52565b81019061105e565b38611c83565b503d612011565b61107d565b909150611eb6600097611eb1565b5050505050909150611d84565b61207291925060203d8111612079575b61206a8183610e52565b810190611125565b90386117c4565b503d612060565b61107d565b61179a9192506117846120af602092833d81116120b8575b6120a78183610e52565b810190611125565b93925050611775565b503d61209d565b61107d565b6120cc613555565b6120d4612142565b565b6120e26120e791611574565b610708565b90565b6120f490546120d6565b90565b60001b90565b9061210960ff916120f7565b9181191691161790565b61211c90610744565b90565b90565b9061213761213261213e92612113565b61211f565b82546120fd565b9055565b61214c60116120ea565b6121945761215c60016011612122565b7f80c8f4ee93129ab9b38a5d893cc03b09e1639b21d4adcda0881f1344acbe5fb9612185610203565b8061218f8161027e565b0390a1565b61219c610203565b6376c855ed60e01b8152806121b36004820161027e565b0390fd5b6121bf6120c4565b565b6121c9613555565b6121d16121fb565b565b6121e76121e26121ec926114f1565b6103f2565b610218565b90565b6121f8906121d3565b90565b61220d61220860006121ef565b6135e8565b565b6122176121c1565b565b61222161147f565b5061222c600a6114ab565b61224261223960006114f4565b60008301611510565b61225861224f60006114f4565b60208301611510565b61226e61226560006114f4565b60408301611510565b61228461227b60006114f4565b60608301611510565b61229a61229160006114f4565b60808301611510565b6122b06122a760006114f4565b60a08301611510565b6122c66122bd60006114f4565b60c08301611510565b6122dc6122d360006114f4565b60e08301611510565b6122f36122e960006114f4565b6101008301611510565b61230a61230060006114f4565b6101208301611510565b60009161235c61231a60006114f4565b9160206123467f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63313ce56790612354610203565b948592611049565b8252818061236c6004820161027e565b03915afa9182156128465760009261280c575b50602061238e6123a4926106a4565b63313ce5679061239c610203565b938492611049565b825281806123b46004820161027e565b03915afa8015612807576123d9926123d4926000926127d7575b50611144565b611168565b926123e261147f565b5b806123fd6123f76123f2611484565b6102eb565b916102eb565b10156124fb576124489060206124327f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb0190612440610203565b948592611049565b825281806124586004820161027e565b03915afa80156124f6576124ac6124a561248a6124be936124c3966000916124c8575b50612484611484565b906110d9565b61249f61249960058790610bba565b906107ef565b906110d9565b88906110d9565b6124b98791849092611533565b611510565b61151e565b6123e3565b6124e9915060203d81116124ef575b6124e18183610e52565b81019061105e565b3861247b565b503d6124d7565b61107d565b5093909392919261250a61147f565b935b8461252661252061251b611484565b6102eb565b916102eb565b10156127cd57612536600f61158e565b61257f6125796125746125666125568a6125506001611187565b9061159b565b6125606064611091565b906115c0565b61256e611484565b906110d9565b6102eb565b916102eb565b106000146127c0576125918215610744565b61269b575b826125e36125dd6125d86125d16125b66125b1878c90611533565b6115f5565b6125cb6125c560058d90610bba565b906107ef565b906115c0565b88906115c0565b6102eb565b916102eb565b11156000146126245750509161261461261a9261260f6126096126209796946005610bba565b906107ef565b6115c0565b906110d9565b9061159b565b5b90565b9093919461268d61264b61269492612645612640868890611533565b6115f5565b9061159b565b96612687612680612665612660878990611533565b6115f5565b61267a61267460058a90610bba565b906107ef565b906115c0565b87906115c0565b906111a3565b925b61151e565b939061250c565b90506126e160206126cb7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb01906126d9610203565b938492611049565b825281806126f16004820161027e565b03915afa9081156127bb5761276c612751612741612727612785956127739560009161278d575b50612721611484565b906110d9565b61273b8a6127356001611187565b9061159b565b906115c0565b61274b601061158e565b906111a3565b61276661276060058a90610bba565b906107ef565b906110d9565b85906110d9565b6127808391879092611533565b611510565b600190612596565b6127ae915060203d81116127b4575b6127a68183610e52565b81019061105e565b38612718565b503d61279c565b61107d565b905061269460009461268f565b5050505050612621565b6127f991925060203d8111612800575b6127f18183610e52565b810190611125565b90386123ce565b503d6127e7565b61107d565b6123a491925061238e612836602092833d811161283f575b61282e8183610e52565b810190611125565b9392505061237f565b503d612824565b61107d565b600090565b60018060a01b031690565b61286761286c91611574565b612850565b90565b612879905461285b565b90565b61288461284b565b5061288f600061286f565b90565b906128a49161289f612e1b565b6128ae565b6128ac612e87565b565b906128d36128cd6128c860126128c2613649565b906109b8565b6120ea565b15610744565b6128e2576128e091612905565b565b6128ea610203565b6322f8556360e01b8152806129016004820161027e565b0390fd5b9061291961291360116120ea565b15610744565b6129285761292691612f5f565b565b612930610203565b63914edb0f60e01b8152806129476004820161027e565b0390fd5b9061295591612892565b565b61295f61147f565b506129a4602061298e7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb019061299c610203565b938492611049565b825281806129b46004820161027e565b03915afa8015612a0c576129db916000916129de575b506129d5601061158e565b906111a3565b90565b6129ff915060203d8111612a05575b6129f78183610e52565b81019061105e565b386129ca565b503d6129ed565b61107d565b90612a2391612a1e612e1b565b612a2d565b612a2b612e87565b565b90612a41612a3b6011611037565b15610744565b612a5057612a4e91612f5f565b565b612a58610203565b63914edb0f60e01b815280612a6f6004820161027e565b0390fd5b90612a7d91612a11565b565b612a87613555565b612a8f612ace565b565b60081b90565b90612aa461ff0091612a91565b9181191691161790565b90612ac3612abe612aca92612113565b61211f565b8254612a97565b9055565b612ad86011611037565b612b2057612ae860016011612aae565b7fbad7871e16f9b9d8b2a6bd6e38ada7c99940913046fe099cffa0040643fb064e612b11610203565b80612b1b8161027e565b0390a1565b612b28610203565b6376c855ed60e01b815280612b3f6004820161027e565b0390fd5b612b4b612a7f565b565b612b5e90612b59613555565b612b60565b565b612b766001612b71601284906109b8565b612122565b612ba07f12c94d2725e3b811140fad6a73350adbd38646149c9a9a62ffc1018bec2ec97c916109ac565b90612ba9610203565b80612bb38161027e565b0390a2565b612bc190612b4d565b565b612bd490612bcf613555565b612bd6565b565b80612bf2612bec612be760006121ef565b610223565b91610223565b14612c0257612c00906135e8565b565b612c2d612c0f60006121ef565b612c17610203565b91829163b20f76e360e01b8352600483016104e5565b0390fd5b612c3a90612bc3565b565b612c4d90612c48613555565b612c80565b565b5190565b90612c5d82612c4f565b811015612c6e576020809102010190565b6105f8565b612c7d9051610223565b90565b90612c8a82612c4f565b90612c9361147f565b5b80612ca7612ca1856102eb565b916102eb565b1015612d3657612d3190612cd96001612cd46012612cce612cc98a8790612c53565b612c73565b906109b8565b612122565b612cec612ce7868390612c53565b612c73565b612d167f12c94d2725e3b811140fad6a73350adbd38646149c9a9a62ffc1018bec2ec97c916109ac565b90612d1f610203565b80612d298161027e565b0390a261151e565b612c94565b50915050565b612d4590612c3c565b565b600090565b612d63612d6891612d5b612d47565b5060126109b8565b6120ea565b90565b612d73612e1b565b612d7b612d85565b612d83612e87565b565b612d8d613656565b565b612d97612d6b565b565b90565b612db0612dab612db592612d99565b6103f2565b6102eb565b90565b612dc26002612d9c565b90565b90612dd2600019916120f7565b9181191691161790565b612df0612deb612df5926102eb565b6103f2565b6102eb565b90565b90565b90612e10612e0b612e1792612ddc565b612df8565b8254612dc5565b9055565b612e25600161158e565b612e3e612e38612e33612db8565b6102eb565b916102eb565b14612e5757612e55612e4e612db8565b6001612dfb565b565b612e5f610203565b6306fda65d60e31b815280612e766004820161027e565b0390fd5b612e846001611187565b90565b612e99612e92612e7a565b6001612dfb565b565b612ea4906103f5565b90565b612eb090612e9b565b90565b612ebc90610411565b90565b612ec8906103f5565b90565b612ed490612ebf565b90565b6000910312612ee257565b61020e565b916020612f09929493612f02604082019660008301906104d8565b01906102ee565b565b612f17612f1c91611574565b610534565b90565b612f299054612f0b565b90565b604090612f56612f5d9496959396612f4c60608401986000850190610d6f565b60208301906104d8565b01906102ee565b565b90612f72612f6c836137af565b15610744565b61353257612f81828290611602565b9081612f96612f9060006114f4565b916102eb565b148015613511575b80156134d7575b6134b457613060612fe4612fd483612fce6064612fc9612fc3610ac8565b91611091565b6111a3565b906115c0565b612fde6064611091565b906110d9565b91613002612ffb85612ff6601061158e565b61159b565b6010612dfb565b61301f61300f601061158e565b6130196064611091565b906115c0565b602061304a7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b63d5abeb0190613058610203565b958692611049565b825281806130706004820161027e565b03915afa9283156134af576130c69361309c926130959260009261347f575b506110d9565b600f612dfb565b6130ad6130a8866106a4565b612ea7565b906130b6613649565b6130bf30612eb3565b91926138a4565b6130ff6130fa6130f57f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b612ecb565b610c69565b63af14052c90803b1561347a576131239160009161311b610203565b938492611049565b82528183816131346004820161027e565b03925af1801561347557613448575b5061317d6131786131737f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610c69565b612ecb565b610c69565b6340c10f1961318a613649565b8492803b15613443576131b1600080946131bc6131a5610203565b97889687958694611049565b845260048401612ee7565b03925af1801561343e57613411575b506131d6600361060e565b926131df61147f565b5b806131f36131ed876102eb565b916102eb565b1015613403578161322061321a61321561320f6003869061061d565b90610669565b61022f565b9161022f565b146132335761322e9061151e565b6131e0565b909192935061324a6132456002612f1f565b610575565b61326361325d638eda7e69936004610cdc565b90610d28565b9061326d30612eb3565b9492813b156133fe576000613295916132a08296613289610203565b998a9788968795611049565b855260048501612f2c565b03925af19182156133f957613326926133cc575b505b6132c76132c2826106a4565b612ea7565b9060206132f47f00000000000000000000000012684d18bdba8e31936f40abce1175366874114f926106a4565b6370a082319061331b61330630612eb3565b9261330f610203565b97889485938493611049565b8352600483016104e5565b03915afa9182156133c75761334393600093613397575b506138f4565b61334b613656565b613353613649565b6133926133807f3f2c9d57c068687834f0de942a9babb9e5acab57d516d3480a3c16ee165a4273926109ac565b92613389610203565b918291826102fb565b0390a2565b6133b991935060203d81116133c0575b6133b18183610e52565b81019061105e565b913861333d565b503d6133a7565b61107d565b6133ec9060003d81116133f2575b6133e48183610e52565b810190612ed7565b386132b4565b503d6133da565b61107d565b611044565b5090506133269192506132b6565b6134319060003d8111613437575b6134298183610e52565b810190612ed7565b386131cb565b503d61341f565b61107d565b611044565b6134689060003d811161346e575b6134608183610e52565b810190612ed7565b38613143565b503d613456565b61107d565b611044565b6134a191925060203d81116134a8575b6134998183610e52565b81019061105e565b903861308f565b503d61348f565b61107d565b6134bc610203565b63199f5a0360e31b8152806134d36004820161027e565b0390fd5b508161350b6135057f00000000000000000000000000000000000000000097432b8379da85b0a000006102eb565b916102eb565b11612fa5565b508161352c613526613521612957565b6102eb565b916102eb565b11612f9e565b61353a610203565b635bfbc03960e01b8152806135516004820161027e565b0390fd5b61355d61287c565b61357661357061356b613649565b610223565b91610223565b0361357d57565b6135a6613588613649565b613590610203565b9182916332b2baa360e01b8352600483016104e5565b0390fd5b906135bb60018060a01b03916120f7565b9181191691161790565b90565b906135dd6135d86135e4926109ac565b6135c5565b82546135aa565b9055565b6135f2600061286f565b6135fd8260006135c8565b9061363161362b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936109ac565b916109ac565b9161363a610203565b806136448161027e565b0390a3565b61365161284b565b503390565b6136b660206136847f000000000000000000000000e30e73cc52ef50a4e4a8b1a3dd0b002b2276f854610905565b6370a08231906136ab61369630612eb3565b9261369f610203565b95869485938493611049565b8352600483016104e5565b03915afa9081156137aa5760009161377c575b50806136de6136d860006114f4565b916102eb565b116136e7575b50565b6136f96136f46002612f1f565b610575565b9063dc7d732390823b1561377757613731926137266000809461371a610203565b96879586948593611049565b8352600483016102fb565b03925af1801561377257613745575b6136e4565b6137659060003d811161376b575b61375d8183610e52565b810190612ed7565b38613740565b503d613753565b61107d565b611044565b61379d915060203d81116137a3575b6137958183610e52565b81019061105e565b386136c9565b503d61378b565b61107d565b6137b7612d47565b506137c2600361060e565b9060006137cd61147f565b5b806137e16137db866102eb565b916102eb565b101561382b578261380e6138086138036137fd6003869061061d565b90610669565b61022f565b9161022f565b146138215761381c9061151e565b6137ce565b5050505060015b90565b50915050613828565b61383d90610411565b90565b63ffffffff1690565b63ffffffff60e01b1690565b61386961386461386e92613840565b611049565b613849565b90565b60409061389b6138a29496959396613891606084019860008501906104d8565b60208301906104d8565b01906102ee565b565b6004926138de6138f295936138ed93946138c56323b872dd92949192613855565b936138ce610203565b9788956020870190815201613871565b60208201810382520383610e52565b613942565b565b9061393b6139409361392c6004949361391363a9059cbb919391613855565b9261391c610203565b9687946020860190815201612ee7565b60208201810382520383610e52565b613942565b565b90600060209161395061147f565b5061395961147f565b50828151910182855af1156139f7573d6000519061398061397a60006114f4565b916102eb565b146000146139dd575061399281613834565b3b6139a66139a060006114f4565b916102eb565b145b6139af5750565b6139bb6139d991613834565b6139c3610203565b918291635274afe760e01b8352600483016104e5565b0390fd5b6139f06139ea6001611187565b916102eb565b14156139a8565b6040513d6000823e3d90fdfea264697066735822122041e1d3d8d8580d0e9626cb8d271bb21b508138507076d840eb4db751942ef1c064736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c00000000000000000000000012684d18bdba8e31936f40abce1175366874114f
-----Decoded View---------------
Arg [0] : baseContracts_ (address): 0x5Ce899AEd04c656776148fc3b1Adbe59e5f13D5c
Arg [1] : treasury_ (address): 0x12684d18BDBA8e31936f40aBcE1175366874114f
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c
Arg [1] : 00000000000000000000000012684d18bdba8e31936f40abce1175366874114f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.