Source Code
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Floor
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 {IERC20Token} from "./interface/IERC20Token.sol";
import {IERC20TokenRebase} from "./interface/IERC20TokenRebase.sol";
import {IFloor} from "./interface/IFloor.sol";
import {IMiscHelper} from "./interface/IMiscHelper.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20 as IERC20Safe} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title Floor
* @dev Price floor mechanism for STTX token
* @notice Manages DUSX deposits and refunds for stability
*/
contract Floor is Ownable, ReentrancyGuard, IFloor {
/// @notice Protocol contracts
IBaseContracts public immutable baseContracts;
IMiscHelper public helper;
bool public helperSet;
IERC20Token public immutable dusx;
IERC20TokenRebase public immutable sttx;
/// @notice Total capital in DUSX
uint256 public capital;
/// @notice Events
event HelperSet(IMiscHelper helper);
event CapitalIncreased(uint256 amount);
event CapitalDecreased(uint256 amount);
event TokensRefunded(address indexed user, uint256 refundAmount);
/// @notice Custom errors
error HelperAlreadySet();
error OnlyHelperCanCall();
error InvalidRefundAmount();
error InvalidBurnAmount();
error TotalSupplyIsZero();
error ZeroAddress();
/// @notice Access control modifier
modifier onlyHelper() {
if (address(helper) != _msgSender()) {
revert OnlyHelperCanCall();
}
_;
}
/**
* @notice Initializes floor with base contracts
* @param baseContracts_ BaseContracts instance for protocol integration
*/
constructor(IBaseContracts baseContracts_) {
_ensureNonzeroAddress(address(baseContracts_));
// Get core contracts from BaseContracts
baseContracts = baseContracts_;
dusx = baseContracts.dusx();
sttx = baseContracts.sttx();
_ensureNonzeroAddress(address(dusx));
_ensureNonzeroAddress(address(sttx));
}
/**
* @notice Sets the helper contract
*/
function setHelper() external onlyOwner {
if (helperSet) revert HelperAlreadySet();
helper = baseContracts.helper();
_ensureNonzeroAddress(address(helper));
helperSet = true;
emit HelperSet(helper);
}
/**
* @notice Deposits DUSX to increase floor capital
* @param msgSender User address
* @param amount Amount to deposit
*/
function deposit(
address msgSender,
uint256 amount
) external nonReentrant onlyHelper {
capital += amount;
SafeERC20.safeTransferFrom(
IERC20Safe(address(dusx)),
msgSender,
address(this),
amount
);
emit CapitalIncreased(amount);
}
/**
* @notice Refunds DUSX by burning STTX
* @param msgSender User address
* @param burnAmount Amount of STTX to burn
*/
function refund(
address msgSender,
uint256 burnAmount
) external nonReentrant onlyHelper {
uint256 refundAmount = getRefundAmount(burnAmount);
if (refundAmount == 0 || refundAmount > capital) {
revert InvalidRefundAmount();
}
capital -= refundAmount;
sttx.burn(msgSender, burnAmount);
SafeERC20.safeTransfer(
IERC20Safe(address(dusx)),
msgSender,
refundAmount
);
sttx.rebase();
emit CapitalDecreased(refundAmount);
emit TokensRefunded(msgSender, refundAmount);
}
/**
* @notice Calculates refund amount based on burn amount
* @param burnAmount Amount of STTX to burn
* @return Refund amount in DUSX
*/
function getRefundAmount(uint256 burnAmount) public view returns (uint256) {
uint256 totalSupply = sttx.totalSupplyRebased() == 0
? sttx.totalSupply()
: sttx.totalSupplyRebased();
if (totalSupply == 0) revert TotalSupplyIsZero();
if (burnAmount > totalSupply) revert InvalidBurnAmount();
return (capital * burnAmount) / totalSupply;
}
// 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"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"HelperAlreadySet","type":"error"},{"inputs":[],"name":"InvalidBurnAmount","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidRefundAmount","type":"error"},{"inputs":[],"name":"OnlyHelperCanCall","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"TotalSupplyIsZero","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"UnauthorizedAccount","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CapitalDecreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CapitalIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IMiscHelper","name":"helper","type":"address"}],"name":"HelperSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundAmount","type":"uint256"}],"name":"TokensRefunded","type":"event"},{"inputs":[],"name":"baseContracts","outputs":[{"internalType":"contract IBaseContracts","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"capital","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dusx","outputs":[{"internalType":"contract IERC20Token","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"burnAmount","type":"uint256"}],"name":"getRefundAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"helper","outputs":[{"internalType":"contract IMiscHelper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"helperSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"},{"internalType":"uint256","name":"burnAmount","type":"uint256"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setHelper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sttx","outputs":[{"internalType":"contract IERC20TokenRebase","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60e0604052346200008a576200001e6200001862000177565b620002fa565b6200002862000090565b6117f96200070a82396080518181816101b30152611252015260a05181818161047101528181610d3b0152610fed015260c05181818161059a015281816108840152818161090701528181610a3801528181610cc20152610d7101526117f990f35b62000096565b60405190565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b90620000c7906200009b565b810190811060018060401b03821117620000e057604052565b620000a5565b90620000fd620000f562000090565b9283620000bb565b565b600080fd5b60018060a01b031690565b6200011a9062000104565b90565b62000128906200010f565b90565b62000136816200011d565b036200013e57565b600080fd5b9050519062000152826200012b565b565b9060208282031262000171576200016e9160000162000143565b90565b620000ff565b6200019a62001f03803803806200018e81620000e6565b92833981019062000154565b90565b90565b620001b9620001b3620001bf9262000104565b6200019d565b62000104565b90565b620001cd90620001a0565b90565b620001db90620001c2565b90565b620001ea90516200011d565b90565b60e01b90565b620001fe906200010f565b90565b6200020c81620001f3565b036200021457565b600080fd5b90505190620002288262000201565b565b906020828203126200024757620002449160000162000219565b90565b620000ff565b60000190565b6200025d62000090565b3d6000823e3d90fd5b62000271906200010f565b90565b6200027f8162000266565b036200028757565b600080fd5b905051906200029b8262000274565b565b90602082820312620002ba57620002b7916000016200028c565b90565b620000ff565b620002cc9051620001f3565b90565b620002da90620001c2565b90565b620002e9905162000266565b90565b620002f790620001c2565b90565b6200030462000494565b620003196200031382620001d0565b620005ac565b60805262000351602062000338620003326080620001de565b620001d0565b6396df10c0906200034862000090565b938492620001ed565b8252818062000363600482016200024d565b03915afa9081156200048e5760009162000459575b5060a052620003b1602062000398620003926080620001de565b620001d0565b63ec4d801990620003a862000090565b938492620001ed565b82528180620003c3600482016200024d565b03915afa90811562000453576000916200041e575b5060c052620003fc620003f6620003f060a0620002c0565b620002cf565b620005ac565b6200041c620004166200041060c0620002dd565b620002ec565b620005ac565b565b62000444915060203d81116200044b575b6200043b8183620000bb565b8101906200029d565b38620003d8565b503d6200042f565b62000253565b6200047f915060203d811162000486575b620004768183620000bb565b8101906200022a565b3862000378565b503d6200046a565b62000253565b6200049e62000541565b565b90565b90565b620004bf620004b9620004c592620004a0565b6200019d565b620004a3565b90565b620004d46001620004a6565b90565b60001b90565b90620004ec60001991620004d7565b9181191691161790565b6200050f620005096200051592620004a3565b6200019d565b620004a3565b90565b90565b90620005356200052f6200053d92620004f6565b62000518565b8254620004dd565b9055565b6200054b62000563565b6200056162000559620004c8565b60016200051b565b565b620005776200057162000601565b6200069c565b565b90565b620005956200058f6200059b9262000579565b6200019d565b62000104565b90565b620005a9906200057c565b90565b620005cd620005c6620005c060006200059e565b6200010f565b916200010f565b14620005d557565b620005df62000090565b63d92e233d60e01b815280620005f8600482016200024d565b0390fd5b600090565b6200060b620005fc565b503390565b60001c90565b60018060a01b031690565b62000630620006369162000610565b62000616565b90565b62000645905462000621565b90565b906200065b60018060a01b0391620004d7565b9181191691161790565b6200067090620001c2565b90565b90565b90620006906200068a620006989262000665565b62000673565b825462000648565b9055565b620006a8600062000639565b620006b582600062000676565b90620006ed620006e67f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09362000665565b9162000665565b91620006f862000090565b8062000704816200024d565b0390a356fe60806040526004361015610013575b61070b565b61001e6000356100ed565b806304cd5294146100e857806325d3d7cf146100e3578063410085df146100de57806347e7ef24146100d957806363b0e66a146100d4578063715018a6146100cf5780638da5cb5b146100ca57806396df10c0146100c5578063a460c213146100c0578063d211fd18146100bb578063ec4d8019146100b6578063f2fde38b146100b15763f8c8dae80361000e576106d6565b61063f565b6105eb565b610563565b6104f7565b6104c2565b61043a565b6103e4565b6103af565b610307565b6102d3565b61023a565b61016c565b60e01c90565b60405190565b600080fd5b600080fd5b90565b61010f81610103565b0361011657565b600080fd5b9050359061012882610106565b565b90602082820312610144576101419160000161011b565b90565b6100fe565b61015290610103565b9052565b919061016a90600060208501940190610149565b565b3461019c5761019861018761018236600461012a565b610871565b61018f6100f3565b91829182610156565b0390f35b6100f9565b60009103126101ac57565b6100fe565b7f000000000000000000000000000000000000000000000000000000000000000090565b60018060a01b031690565b90565b6101f76101f26101fc926101d5565b6101e0565b6101d5565b90565b610208906101e3565b90565b610214906101ff565b90565b6102209061020b565b9052565b919061023890600060208501940190610217565b565b3461026a5761024a3660046101a1565b6102666102556101b1565b61025d6100f3565b91829182610224565b0390f35b6100f9565b610278906101d5565b90565b6102848161026f565b0361028b57565b600080fd5b9050359061029d8261027b565b565b91906040838203126102c857806102bc6102c59260008601610290565b9360200161011b565b90565b6100fe565b60000190565b34610302576102ec6102e636600461029f565b90610f0c565b6102f46100f3565b806102fe816102cd565b0390f35b6100f9565b346103365761032061031a36600461029f565b90611063565b6103286100f3565b80610332816102cd565b0390f35b6100f9565b1c90565b60018060a01b031690565b61035a90600861035f930261033b565b61033f565b90565b9061036d915461034a565b90565b61037d6002600090610362565b90565b610389906101ff565b90565b61039590610380565b9052565b91906103ad9060006020850194019061038c565b565b346103df576103bf3660046101a1565b6103db6103ca610370565b6103d26100f3565b91829182610399565b0390f35b6100f9565b34610412576103f43660046101a1565b6103fc6110bd565b6104046100f3565b8061040e816102cd565b0390f35b6100f9565b6104209061026f565b9052565b919061043890600060208501940190610417565b565b3461046a5761044a3660046101a1565b6104666104556110f8565b61045d6100f3565b91829182610424565b0390f35b6100f9565b7f000000000000000000000000000000000000000000000000000000000000000090565b61049c906101ff565b90565b6104a890610493565b9052565b91906104c09060006020850194019061049f565b565b346104f2576104d23660046101a1565b6104ee6104dd61046f565b6104e56100f3565b918291826104ac565b0390f35b6100f9565b34610525576105073660046101a1565b61050f61137b565b6105176100f3565b80610521816102cd565b0390f35b6100f9565b90565b61053d906008610542930261033b565b61052a565b90565b90610550915461052d565b90565b6105606003600090610545565b90565b34610593576105733660046101a1565b61058f61057e610553565b6105866100f3565b91829182610156565b0390f35b6100f9565b7f000000000000000000000000000000000000000000000000000000000000000090565b6105c5906101ff565b90565b6105d1906105bc565b9052565b91906105e9906000602085019401906105c8565b565b3461061b576105fb3660046101a1565b610617610606610598565b61060e6100f3565b918291826105d5565b0390f35b6100f9565b9060208282031261063a5761063791600001610290565b90565b6100fe565b3461066d57610657610652366004610620565b6113f3565b61065f6100f3565b80610669816102cd565b0390f35b6100f9565b60ff1690565b61068890600861068d930261033b565b610672565b90565b9061069b9154610678565b90565b6106ab6002601490610690565b90565b151590565b6106bc906106ae565b9052565b91906106d4906000602085019401906106b3565b565b34610706576106e63660046101a1565b6107026106f161069e565b6106f96100f3565b918291826106c0565b0390f35b6100f9565b600080fd5b600090565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b906107449061071a565b810190811067ffffffffffffffff82111761075e57604052565b610724565b60e01b90565b9050519061077682610106565b565b906020828203126107925761078f91600001610769565b90565b6100fe565b61079f6100f3565b3d6000823e3d90fd5b90565b6107bf6107ba6107c4926107a8565b6101e0565b610103565b90565b60001c90565b6107d96107de916107c7565b61052a565b90565b6107eb90546107cd565b90565b634e487b7160e01b600052601160045260246000fd5b61081361081991939293610103565b92610103565b91610825838202610103565b92818404149015171561083457565b6107ee565b634e487b7160e01b600052601260045260246000fd5b61085b61086191610103565b91610103565b90811561086c570490565b610839565b610879610710565b506108be60206108a87f00000000000000000000000000000000000000000000000000000000000000006105bc565b63a291eeda906108b66100f3565b938492610763565b825281806108ce600482016102cd565b03915afa908115610afc57600091610ace575b506108f56108ef60006107ab565b91610103565b14600014610a2e57610941602061092b7f00000000000000000000000000000000000000000000000000000000000000006105bc565b6318160ddd906109396100f3565b938492610763565b82528180610951600482016102cd565b03915afa908115610a29576000916109fb575b505b8061097a61097460006107ab565b91610103565b146109d8578161099261098c83610103565b91610103565b116109b5576109ad6109b2926109a860036107e1565b610804565b61084f565b90565b6109bd6100f3565b6302075cc160e41b8152806109d4600482016102cd565b0390fd5b6109e06100f3565b634253080360e01b8152806109f7600482016102cd565b0390fd5b610a1c915060203d8111610a22575b610a14818361073a565b810190610778565b38610964565b503d610a0a565b610797565b610a726020610a5c7f00000000000000000000000000000000000000000000000000000000000000006105bc565b63a291eeda90610a6a6100f3565b938492610763565b82528180610a82600482016102cd565b03915afa908115610ac957600091610a9b575b50610966565b610abc915060203d8111610ac2575b610ab4818361073a565b810190610778565b38610a95565b503d610aaa565b610797565b610aef915060203d8111610af5575b610ae7818361073a565b810190610778565b386108e1565b503d610add565b610797565b90610b1391610b0e61142a565b610b3e565b610b1b6114b5565b565b610b29610b2e916107c7565b61033f565b90565b610b3b9054610b1d565b90565b90610b51610b4c6002610b31565b610380565b610b6a610b64610b5f6114c9565b61026f565b9161026f565b03610b7a57610b7891610c76565b565b610b826100f3565b6309b86dbf60e41b815280610b99600482016102cd565b0390fd5b610bac610bb291939293610103565b92610103565b8203918211610bbd57565b6107ee565b60001b90565b90610bd560001991610bc2565b9181191691161790565b610bf3610bee610bf892610103565b6101e0565b610103565b90565b90565b90610c13610c0e610c1a92610bdf565b610bfb565b8254610bc8565b9055565b6000910312610c2957565b6100fe565b916020610c50929493610c4960408201966000830190610417565b0190610149565b565b610c5b906101e3565b90565b610c6790610c52565b90565b610c73906101ff565b90565b610c7f82610871565b9182610c94610c8e60006107ab565b91610103565b148015610ee9575b610ec657610cbd610cb684610cb160036107e1565b610b9d565b6003610bfe565b610ce67f00000000000000000000000000000000000000000000000000000000000000006105bc565b90639dc29fac90839092803b15610ec157610d1560008094610d20610d096100f3565b97889687958694610763565b845260048401610c2e565b03925af18015610ebc57610e8f575b50610d6c610d64610d5f7f0000000000000000000000000000000000000000000000000000000000000000610493565b610c5e565b828491611513565b610d957f00000000000000000000000000000000000000000000000000000000000000006105bc565b63af14052c90803b15610e8a57610db991600091610db16100f3565b938492610763565b8252818381610dca600482016102cd565b03925af18015610e8557610e58575b5081610e117f654af6168cbb344e926afc2c43de9e1471105baf20313fe55f49223791dbfe1391610e086100f3565b91829182610156565b0390a1610e53610e417f4a38df4d86b2d93d9427931480e831f8dbede6c4d0fdc4490340fddc0c33627a92610c6a565b92610e4a6100f3565b91829182610156565b0390a2565b610e789060003d8111610e7e575b610e70818361073a565b810190610c1e565b38610dd9565b503d610e66565b610797565b610715565b610eaf9060003d8111610eb5575b610ea7818361073a565b810190610c1e565b38610d2f565b503d610e9d565b610797565b610715565b610ece6100f3565b6316365d5f60e01b815280610ee5600482016102cd565b0390fd5b5082610f06610f00610efb60036107e1565b610103565b91610103565b11610c9c565b90610f1691610b01565b565b90610f2a91610f2561142a565b610f34565b610f326114b5565b565b90610f47610f426002610b31565b610380565b610f60610f5a610f556114c9565b61026f565b9161026f565b03610f7057610f6e91610fc4565b565b610f786100f3565b6309b86dbf60e41b815280610f8f600482016102cd565b0390fd5b610fa2610fa891939293610103565b92610103565b8201809211610fb357565b6107ee565b610fc1906101ff565b90565b61102890610fe5610fde84610fd960036107e1565b610f93565b6003610bfe565b6110166110117f0000000000000000000000000000000000000000000000000000000000000000610493565b610c5e565b9061102030610fb8565b908492611594565b61105e7ff6b55bab6d7e270c7d22c26e35d0aac12c5c55ec34526cf4e7fff7015bbdf562916110556100f3565b91829182610156565b0390a1565b9061106d91610f18565b565b6110776115e4565b61107f6110a9565b565b61109561109061109a926107a8565b6101e0565b6101d5565b90565b6110a690611081565b90565b6110bb6110b6600061109d565b61165c565b565b6110c561106f565b565b600090565b60018060a01b031690565b6110e36110e8916107c7565b6110cc565b90565b6110f590546110d7565b90565b6111006110c7565b5061110b60006110eb565b90565b6111166115e4565b61111e61123a565b565b60a01c90565b61113261113791611120565b610672565b90565b6111449054611126565b90565b6111509061026f565b90565b61115c81611147565b0361116357565b600080fd5b9050519061117582611153565b565b906020828203126111915761118e91600001611168565b90565b6100fe565b906111a760018060a01b0391610bc2565b9181191691161790565b6111ba906101e3565b90565b6111c6906111b1565b90565b90565b906111e16111dc6111e8926111bd565b6111c9565b8254611196565b9055565b60a01b90565b9061120160ff60a01b916111ec565b9181191691161790565b611214906106ae565b90565b90565b9061122f61122a6112369261120b565b611217565b82546111f2565b9055565b611244600261113a565b6113585761128c60206112767f000000000000000000000000000000000000000000000000000000000000000061020b565b6363b0e66a906112846100f3565b938492610763565b8252818061129c600482016102cd565b03915afa8015611353576112ba91600091611325575b5060026111cc565b6112d46112cf6112ca6002610b31565b610380565b6116bd565b6112e06001600261121a565b6112ea6002610b31565b6113207f33ccdeef2c3810751e8ce3f0228fb9965b606a76744466a6889a7069325bfd97916113176100f3565b91829182610399565b0390a1565b611346915060203d811161134c575b61133e818361073a565b810190611177565b386112b2565b503d611334565b610797565b6113606100f3565b634f4bb3e960e11b815280611377600482016102cd565b0390fd5b61138361110e565b565b611396906113916115e4565b611398565b565b806113b46113ae6113a9600061109d565b61026f565b9161026f565b146113c4576113c29061165c565b565b6113ef6113d1600061109d565b6113d96100f3565b91829163b20f76e360e01b835260048301610424565b0390fd5b6113fc90611385565b565b90565b61141561141061141a926113fe565b6101e0565b610103565b90565b6114276002611401565b90565b61143460016107e1565b61144d61144761144261141d565b610103565b91610103565b146114665761146461145d61141d565b6001610bfe565b565b61146e6100f3565b6306fda65d60e31b815280611485600482016102cd565b0390fd5b90565b6114a061149b6114a592611489565b6101e0565b610103565b90565b6114b2600161148c565b90565b6114c76114c06114a8565b6001610bfe565b565b6114d16110c7565b503390565b6114df906101ff565b90565b63ffffffff1690565b63ffffffff60e01b1690565b61150b611506611510926114e2565b610763565b6114eb565b90565b9061155a61155f9361154b6004949361153263a9059cbb9193916114f7565b9261153b6100f3565b9687946020860190815201610c2e565b6020820181038252038361073a565b611702565b565b60409061158b611592949695939661158160608401986000850190610417565b6020830190610417565b0190610149565b565b6004926115ce6115e295936115dd93946115b56323b872dd929491926114f7565b936115be6100f3565b9788956020870190815201611561565b6020820181038252038361073a565b611702565b565b6115ec6110f8565b6116056115ff6115fa6114c9565b61026f565b9161026f565b0361160c57565b6116356116176114c9565b61161f6100f3565b9182916332b2baa360e01b835260048301610424565b0390fd5b90565b9061165161164c61165892610c6a565b611639565b8254611196565b9055565b61166660006110eb565b61167182600061163c565b906116a561169f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610c6a565b91610c6a565b916116ae6100f3565b806116b8816102cd565b0390a3565b6116d86116d26116cd600061109d565b61026f565b9161026f565b146116df57565b6116e76100f3565b63d92e233d60e01b8152806116fe600482016102cd565b0390fd5b906000602091611710610710565b50611719610710565b50828151910182855af1156117b7573d6000519061174061173a60006107ab565b91610103565b1460001461179d5750611752816114d6565b3b61176661176060006107ab565b91610103565b145b61176f5750565b61177b611799916114d6565b6117836100f3565b918291635274afe760e01b835260048301610424565b0390fd5b6117b06117aa600161148c565b91610103565b1415611768565b6040513d6000823e3d90fdfea2646970667358221220bdd5d482b95df6d6617e1ecca0fab281e3cdb02dcf24a389068f07c77592594864736f6c634300081800330000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c
Deployed Bytecode
0x60806040526004361015610013575b61070b565b61001e6000356100ed565b806304cd5294146100e857806325d3d7cf146100e3578063410085df146100de57806347e7ef24146100d957806363b0e66a146100d4578063715018a6146100cf5780638da5cb5b146100ca57806396df10c0146100c5578063a460c213146100c0578063d211fd18146100bb578063ec4d8019146100b6578063f2fde38b146100b15763f8c8dae80361000e576106d6565b61063f565b6105eb565b610563565b6104f7565b6104c2565b61043a565b6103e4565b6103af565b610307565b6102d3565b61023a565b61016c565b60e01c90565b60405190565b600080fd5b600080fd5b90565b61010f81610103565b0361011657565b600080fd5b9050359061012882610106565b565b90602082820312610144576101419160000161011b565b90565b6100fe565b61015290610103565b9052565b919061016a90600060208501940190610149565b565b3461019c5761019861018761018236600461012a565b610871565b61018f6100f3565b91829182610156565b0390f35b6100f9565b60009103126101ac57565b6100fe565b7f0000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c90565b60018060a01b031690565b90565b6101f76101f26101fc926101d5565b6101e0565b6101d5565b90565b610208906101e3565b90565b610214906101ff565b90565b6102209061020b565b9052565b919061023890600060208501940190610217565b565b3461026a5761024a3660046101a1565b6102666102556101b1565b61025d6100f3565b91829182610224565b0390f35b6100f9565b610278906101d5565b90565b6102848161026f565b0361028b57565b600080fd5b9050359061029d8261027b565b565b91906040838203126102c857806102bc6102c59260008601610290565b9360200161011b565b90565b6100fe565b60000190565b34610302576102ec6102e636600461029f565b90610f0c565b6102f46100f3565b806102fe816102cd565b0390f35b6100f9565b346103365761032061031a36600461029f565b90611063565b6103286100f3565b80610332816102cd565b0390f35b6100f9565b1c90565b60018060a01b031690565b61035a90600861035f930261033b565b61033f565b90565b9061036d915461034a565b90565b61037d6002600090610362565b90565b610389906101ff565b90565b61039590610380565b9052565b91906103ad9060006020850194019061038c565b565b346103df576103bf3660046101a1565b6103db6103ca610370565b6103d26100f3565b91829182610399565b0390f35b6100f9565b34610412576103f43660046101a1565b6103fc6110bd565b6104046100f3565b8061040e816102cd565b0390f35b6100f9565b6104209061026f565b9052565b919061043890600060208501940190610417565b565b3461046a5761044a3660046101a1565b6104666104556110f8565b61045d6100f3565b91829182610424565b0390f35b6100f9565b7f000000000000000000000000e30e73cc52ef50a4e4a8b1a3dd0b002b2276f85490565b61049c906101ff565b90565b6104a890610493565b9052565b91906104c09060006020850194019061049f565b565b346104f2576104d23660046101a1565b6104ee6104dd61046f565b6104e56100f3565b918291826104ac565b0390f35b6100f9565b34610525576105073660046101a1565b61050f61137b565b6105176100f3565b80610521816102cd565b0390f35b6100f9565b90565b61053d906008610542930261033b565b61052a565b90565b90610550915461052d565b90565b6105606003600090610545565b90565b34610593576105733660046101a1565b61058f61057e610553565b6105866100f3565b91829182610156565b0390f35b6100f9565b7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea90565b6105c5906101ff565b90565b6105d1906105bc565b9052565b91906105e9906000602085019401906105c8565b565b3461061b576105fb3660046101a1565b610617610606610598565b61060e6100f3565b918291826105d5565b0390f35b6100f9565b9060208282031261063a5761063791600001610290565b90565b6100fe565b3461066d57610657610652366004610620565b6113f3565b61065f6100f3565b80610669816102cd565b0390f35b6100f9565b60ff1690565b61068890600861068d930261033b565b610672565b90565b9061069b9154610678565b90565b6106ab6002601490610690565b90565b151590565b6106bc906106ae565b9052565b91906106d4906000602085019401906106b3565b565b34610706576106e63660046101a1565b6107026106f161069e565b6106f96100f3565b918291826106c0565b0390f35b6100f9565b600080fd5b600090565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b906107449061071a565b810190811067ffffffffffffffff82111761075e57604052565b610724565b60e01b90565b9050519061077682610106565b565b906020828203126107925761078f91600001610769565b90565b6100fe565b61079f6100f3565b3d6000823e3d90fd5b90565b6107bf6107ba6107c4926107a8565b6101e0565b610103565b90565b60001c90565b6107d96107de916107c7565b61052a565b90565b6107eb90546107cd565b90565b634e487b7160e01b600052601160045260246000fd5b61081361081991939293610103565b92610103565b91610825838202610103565b92818404149015171561083457565b6107ee565b634e487b7160e01b600052601260045260246000fd5b61085b61086191610103565b91610103565b90811561086c570490565b610839565b610879610710565b506108be60206108a87f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea6105bc565b63a291eeda906108b66100f3565b938492610763565b825281806108ce600482016102cd565b03915afa908115610afc57600091610ace575b506108f56108ef60006107ab565b91610103565b14600014610a2e57610941602061092b7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea6105bc565b6318160ddd906109396100f3565b938492610763565b82528180610951600482016102cd565b03915afa908115610a29576000916109fb575b505b8061097a61097460006107ab565b91610103565b146109d8578161099261098c83610103565b91610103565b116109b5576109ad6109b2926109a860036107e1565b610804565b61084f565b90565b6109bd6100f3565b6302075cc160e41b8152806109d4600482016102cd565b0390fd5b6109e06100f3565b634253080360e01b8152806109f7600482016102cd565b0390fd5b610a1c915060203d8111610a22575b610a14818361073a565b810190610778565b38610964565b503d610a0a565b610797565b610a726020610a5c7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea6105bc565b63a291eeda90610a6a6100f3565b938492610763565b82528180610a82600482016102cd565b03915afa908115610ac957600091610a9b575b50610966565b610abc915060203d8111610ac2575b610ab4818361073a565b810190610778565b38610a95565b503d610aaa565b610797565b610aef915060203d8111610af5575b610ae7818361073a565b810190610778565b386108e1565b503d610add565b610797565b90610b1391610b0e61142a565b610b3e565b610b1b6114b5565b565b610b29610b2e916107c7565b61033f565b90565b610b3b9054610b1d565b90565b90610b51610b4c6002610b31565b610380565b610b6a610b64610b5f6114c9565b61026f565b9161026f565b03610b7a57610b7891610c76565b565b610b826100f3565b6309b86dbf60e41b815280610b99600482016102cd565b0390fd5b610bac610bb291939293610103565b92610103565b8203918211610bbd57565b6107ee565b60001b90565b90610bd560001991610bc2565b9181191691161790565b610bf3610bee610bf892610103565b6101e0565b610103565b90565b90565b90610c13610c0e610c1a92610bdf565b610bfb565b8254610bc8565b9055565b6000910312610c2957565b6100fe565b916020610c50929493610c4960408201966000830190610417565b0190610149565b565b610c5b906101e3565b90565b610c6790610c52565b90565b610c73906101ff565b90565b610c7f82610871565b9182610c94610c8e60006107ab565b91610103565b148015610ee9575b610ec657610cbd610cb684610cb160036107e1565b610b9d565b6003610bfe565b610ce67f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea6105bc565b90639dc29fac90839092803b15610ec157610d1560008094610d20610d096100f3565b97889687958694610763565b845260048401610c2e565b03925af18015610ebc57610e8f575b50610d6c610d64610d5f7f000000000000000000000000e30e73cc52ef50a4e4a8b1a3dd0b002b2276f854610493565b610c5e565b828491611513565b610d957f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea6105bc565b63af14052c90803b15610e8a57610db991600091610db16100f3565b938492610763565b8252818381610dca600482016102cd565b03925af18015610e8557610e58575b5081610e117f654af6168cbb344e926afc2c43de9e1471105baf20313fe55f49223791dbfe1391610e086100f3565b91829182610156565b0390a1610e53610e417f4a38df4d86b2d93d9427931480e831f8dbede6c4d0fdc4490340fddc0c33627a92610c6a565b92610e4a6100f3565b91829182610156565b0390a2565b610e789060003d8111610e7e575b610e70818361073a565b810190610c1e565b38610dd9565b503d610e66565b610797565b610715565b610eaf9060003d8111610eb5575b610ea7818361073a565b810190610c1e565b38610d2f565b503d610e9d565b610797565b610715565b610ece6100f3565b6316365d5f60e01b815280610ee5600482016102cd565b0390fd5b5082610f06610f00610efb60036107e1565b610103565b91610103565b11610c9c565b90610f1691610b01565b565b90610f2a91610f2561142a565b610f34565b610f326114b5565b565b90610f47610f426002610b31565b610380565b610f60610f5a610f556114c9565b61026f565b9161026f565b03610f7057610f6e91610fc4565b565b610f786100f3565b6309b86dbf60e41b815280610f8f600482016102cd565b0390fd5b610fa2610fa891939293610103565b92610103565b8201809211610fb357565b6107ee565b610fc1906101ff565b90565b61102890610fe5610fde84610fd960036107e1565b610f93565b6003610bfe565b6110166110117f000000000000000000000000e30e73cc52ef50a4e4a8b1a3dd0b002b2276f854610493565b610c5e565b9061102030610fb8565b908492611594565b61105e7ff6b55bab6d7e270c7d22c26e35d0aac12c5c55ec34526cf4e7fff7015bbdf562916110556100f3565b91829182610156565b0390a1565b9061106d91610f18565b565b6110776115e4565b61107f6110a9565b565b61109561109061109a926107a8565b6101e0565b6101d5565b90565b6110a690611081565b90565b6110bb6110b6600061109d565b61165c565b565b6110c561106f565b565b600090565b60018060a01b031690565b6110e36110e8916107c7565b6110cc565b90565b6110f590546110d7565b90565b6111006110c7565b5061110b60006110eb565b90565b6111166115e4565b61111e61123a565b565b60a01c90565b61113261113791611120565b610672565b90565b6111449054611126565b90565b6111509061026f565b90565b61115c81611147565b0361116357565b600080fd5b9050519061117582611153565b565b906020828203126111915761118e91600001611168565b90565b6100fe565b906111a760018060a01b0391610bc2565b9181191691161790565b6111ba906101e3565b90565b6111c6906111b1565b90565b90565b906111e16111dc6111e8926111bd565b6111c9565b8254611196565b9055565b60a01b90565b9061120160ff60a01b916111ec565b9181191691161790565b611214906106ae565b90565b90565b9061122f61122a6112369261120b565b611217565b82546111f2565b9055565b611244600261113a565b6113585761128c60206112767f0000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c61020b565b6363b0e66a906112846100f3565b938492610763565b8252818061129c600482016102cd565b03915afa8015611353576112ba91600091611325575b5060026111cc565b6112d46112cf6112ca6002610b31565b610380565b6116bd565b6112e06001600261121a565b6112ea6002610b31565b6113207f33ccdeef2c3810751e8ce3f0228fb9965b606a76744466a6889a7069325bfd97916113176100f3565b91829182610399565b0390a1565b611346915060203d811161134c575b61133e818361073a565b810190611177565b386112b2565b503d611334565b610797565b6113606100f3565b634f4bb3e960e11b815280611377600482016102cd565b0390fd5b61138361110e565b565b611396906113916115e4565b611398565b565b806113b46113ae6113a9600061109d565b61026f565b9161026f565b146113c4576113c29061165c565b565b6113ef6113d1600061109d565b6113d96100f3565b91829163b20f76e360e01b835260048301610424565b0390fd5b6113fc90611385565b565b90565b61141561141061141a926113fe565b6101e0565b610103565b90565b6114276002611401565b90565b61143460016107e1565b61144d61144761144261141d565b610103565b91610103565b146114665761146461145d61141d565b6001610bfe565b565b61146e6100f3565b6306fda65d60e31b815280611485600482016102cd565b0390fd5b90565b6114a061149b6114a592611489565b6101e0565b610103565b90565b6114b2600161148c565b90565b6114c76114c06114a8565b6001610bfe565b565b6114d16110c7565b503390565b6114df906101ff565b90565b63ffffffff1690565b63ffffffff60e01b1690565b61150b611506611510926114e2565b610763565b6114eb565b90565b9061155a61155f9361154b6004949361153263a9059cbb9193916114f7565b9261153b6100f3565b9687946020860190815201610c2e565b6020820181038252038361073a565b611702565b565b60409061158b611592949695939661158160608401986000850190610417565b6020830190610417565b0190610149565b565b6004926115ce6115e295936115dd93946115b56323b872dd929491926114f7565b936115be6100f3565b9788956020870190815201611561565b6020820181038252038361073a565b611702565b565b6115ec6110f8565b6116056115ff6115fa6114c9565b61026f565b9161026f565b0361160c57565b6116356116176114c9565b61161f6100f3565b9182916332b2baa360e01b835260048301610424565b0390fd5b90565b9061165161164c61165892610c6a565b611639565b8254611196565b9055565b61166660006110eb565b61167182600061163c565b906116a561169f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610c6a565b91610c6a565b916116ae6100f3565b806116b8816102cd565b0390a3565b6116d86116d26116cd600061109d565b61026f565b9161026f565b146116df57565b6116e76100f3565b63d92e233d60e01b8152806116fe600482016102cd565b0390fd5b906000602091611710610710565b50611719610710565b50828151910182855af1156117b7573d6000519061174061173a60006107ab565b91610103565b1460001461179d5750611752816114d6565b3b61176661176060006107ab565b91610103565b145b61176f5750565b61177b611799916114d6565b6117836100f3565b918291635274afe760e01b835260048301610424565b0390fd5b6117b06117aa600161148c565b91610103565b1415611768565b6040513d6000823e3d90fdfea2646970667358221220bdd5d482b95df6d6617e1ecca0fab281e3cdb02dcf24a389068f07c77592594864736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c
-----Decoded View---------------
Arg [0] : baseContracts_ (address): 0x5Ce899AEd04c656776148fc3b1Adbe59e5f13D5c
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.