Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x61012060 | 20460672 | 555 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Tranche
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 500 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;
import {ERC20} from "src/token/ERC20.sol";
import {IERC20, IERC20Metadata} from "src/interfaces/IERC20.sol";
import {
IHook,
HookData,
SUCCESS_CODE_ID,
SUCCESS_MESSAGE,
ERROR_CODE_ID,
ERROR_MESSAGE
} from "src/interfaces/token/IHook.sol";
import {IERC7575Share, IERC165} from "src/interfaces/IERC7575.sol";
import {ITranche, IERC1404} from "src/interfaces/token/ITranche.sol";
import {MathLib} from "src/libraries/MathLib.sol";
/// @title Tranche Token
/// @notice Extension of ERC20 + ERC1404 for tranche tokens,
/// integrating an external hook optionally for ERC20 callbacks and ERC1404 checks.
contract Tranche is ERC20, ITranche {
using MathLib for uint256;
mapping(address => Balance) private balances;
/// @inheritdoc ITranche
address public hook;
/// @inheritdoc IERC7575Share
mapping(address asset => address) public vault;
constructor(uint8 decimals_) ERC20(decimals_) {}
modifier authOrHook() {
require(wards[msg.sender] == 1 || msg.sender == hook, "Tranche/not-authorized");
_;
}
// --- Administration ---
/// @inheritdoc ITranche
function file(bytes32 what, address data) external authOrHook {
if (what == "hook") hook = data;
else revert("Tranche/file-unrecognized-param");
emit File(what, data);
}
/// @inheritdoc ITranche
function file(bytes32 what, string memory data) public override(ERC20, ITranche) auth {
super.file(what, data);
}
/// @inheritdoc ITranche
function updateVault(address asset, address vault_) external auth {
vault[asset] = vault_;
emit VaultUpdate(asset, vault_);
}
// --- ERC20 overrides ---
function _balanceOf(address user) internal view override returns (uint256) {
return balances[user].amount;
}
function _setBalance(address user, uint256 value) internal override {
balances[user].amount = value.toUint128();
}
/// @inheritdoc ITranche
function hookDataOf(address user) public view returns (bytes16) {
return balances[user].hookData;
}
/// @inheritdoc ITranche
function setHookData(address user, bytes16 hookData) public authOrHook {
balances[user].hookData = hookData;
emit SetHookData(user, hookData);
}
/// @inheritdoc IERC20
function transfer(address to, uint256 value) public override(ERC20, IERC20) returns (bool success) {
success = super.transfer(to, value);
_onTransfer(msg.sender, to, value);
}
/// @inheritdoc IERC20
function transferFrom(address from, address to, uint256 value)
public
override(ERC20, IERC20)
returns (bool success)
{
success = super.transferFrom(from, to, value);
_onTransfer(from, to, value);
}
/// @inheritdoc ITranche
function mint(address to, uint256 value) public override(ERC20, ITranche) {
super.mint(to, value);
require(totalSupply <= type(uint128).max, "Tranche/exceeds-max-supply");
_onTransfer(address(0), to, value);
}
/// @inheritdoc ITranche
function burn(address from, uint256 value) public override(ERC20, ITranche) {
super.burn(from, value);
_onTransfer(from, address(0), value);
}
function _onTransfer(address from, address to, uint256 value) internal {
require(
hook == address(0)
|| IHook(hook).onERC20Transfer(from, to, value, HookData(hookDataOf(from), hookDataOf(to)))
== IHook.onERC20Transfer.selector,
"Tranche/restrictions-failed"
);
}
/// @inheritdoc ITranche
function authTransferFrom(address sender, address from, address to, uint256 value)
public
auth
returns (bool success)
{
success = _transferFrom(sender, from, to, value);
require(
hook == address(0)
|| IHook(hook).onERC20AuthTransfer(sender, from, to, value, HookData(hookDataOf(from), hookDataOf(to)))
== IHook.onERC20AuthTransfer.selector,
"Tranche/restrictions-failed"
);
}
// --- ERC1404 implementation ---
/// @inheritdoc ITranche
function checkTransferRestriction(address from, address to, uint256 value) public view returns (bool) {
return detectTransferRestriction(from, to, value) == SUCCESS_CODE_ID;
}
/// @inheritdoc IERC1404
function detectTransferRestriction(address from, address to, uint256 value) public view returns (uint8) {
if (hook == address(0)) return SUCCESS_CODE_ID;
return IHook(hook).checkERC20Transfer(from, to, value, HookData(hookDataOf(from), hookDataOf(to)))
? SUCCESS_CODE_ID
: ERROR_CODE_ID;
}
/// @inheritdoc IERC1404
function messageForTransferRestriction(uint8 restrictionCode) external pure returns (string memory) {
return restrictionCode == SUCCESS_CODE_ID ? SUCCESS_MESSAGE : ERROR_MESSAGE;
}
// --- ERC165 support ---
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
return interfaceId == type(IERC7575Share).interfaceId || interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;
import {Auth} from "src/Auth.sol";
import {EIP712Lib} from "src/libraries/EIP712Lib.sol";
import {SignatureLib} from "src/libraries/SignatureLib.sol";
import {IERC20, IERC20Metadata, IERC20Permit} from "src/interfaces/IERC20.sol";
/// @title ERC20
/// @notice Standard ERC-20 implementation, with mint/burn functionality and permit logic.
/// @author Modified from https://github.com/makerdao/xdomain-dss/blob/master/src/Dai.sol
contract ERC20 is Auth, IERC20Metadata, IERC20Permit {
/// @inheritdoc IERC20Metadata
string public name;
/// @inheritdoc IERC20Metadata
string public symbol;
/// @inheritdoc IERC20Metadata
uint8 public immutable decimals;
/// @inheritdoc IERC20
uint256 public totalSupply;
mapping(address => uint256) private balances;
/// @inheritdoc IERC20
mapping(address => mapping(address => uint256)) public allowance;
/// @inheritdoc IERC20Permit
mapping(address => uint256) public nonces;
// --- EIP712 ---
bytes32 private immutable nameHash;
bytes32 private immutable versionHash;
uint256 public immutable deploymentChainId;
bytes32 private immutable _DOMAIN_SEPARATOR;
bytes32 public constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
// --- Events ---
event File(bytes32 indexed what, string data);
constructor(uint8 decimals_) Auth(msg.sender) {
decimals = decimals_;
nameHash = keccak256(bytes("Centrifuge"));
versionHash = keccak256(bytes("1"));
deploymentChainId = block.chainid;
_DOMAIN_SEPARATOR = EIP712Lib.calculateDomainSeparator(nameHash, versionHash);
}
function _balanceOf(address user) internal view virtual returns (uint256) {
return balances[user];
}
/// @inheritdoc IERC20
function balanceOf(address user) public view virtual returns (uint256) {
return _balanceOf(user);
}
function _setBalance(address user, uint256 value) internal virtual {
balances[user] = value;
}
/// @inheritdoc IERC20Permit
function DOMAIN_SEPARATOR() public view returns (bytes32) {
return block.chainid == deploymentChainId
? _DOMAIN_SEPARATOR
: EIP712Lib.calculateDomainSeparator(nameHash, versionHash);
}
// --- Administration ---
function file(bytes32 what, string memory data) public virtual auth {
if (what == "name") name = data;
else if (what == "symbol") symbol = data;
else revert("ERC20/file-unrecognized-param");
emit File(what, data);
}
// --- ERC20 Mutations ---
/// @inheritdoc IERC20
function transfer(address to, uint256 value) public virtual returns (bool) {
require(to != address(0) && to != address(this), "ERC20/invalid-address");
uint256 balance = balanceOf(msg.sender);
require(balance >= value, "ERC20/insufficient-balance");
unchecked {
_setBalance(msg.sender, _balanceOf(msg.sender) - value);
// note: we don't need an overflow check here b/c sum of all balances == totalSupply
_setBalance(to, _balanceOf(to) + value);
}
emit Transfer(msg.sender, to, value);
return true;
}
/// @inheritdoc IERC20
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
return _transferFrom(msg.sender, from, to, value);
}
function _transferFrom(address sender, address from, address to, uint256 value) internal virtual returns (bool) {
require(to != address(0) && to != address(this), "ERC20/invalid-address");
uint256 balance = balanceOf(from);
require(balance >= value, "ERC20/insufficient-balance");
if (from != sender) {
uint256 allowed = allowance[from][sender];
if (allowed != type(uint256).max) {
require(allowed >= value, "ERC20/insufficient-allowance");
unchecked {
allowance[from][sender] = allowed - value;
}
}
}
unchecked {
_setBalance(from, _balanceOf(from) - value);
// note: we don't need an overflow check here b/c sum of all balances == totalSupply
_setBalance(to, _balanceOf(to) + value);
}
emit Transfer(from, to, value);
return true;
}
/// @inheritdoc IERC20
function approve(address spender, uint256 value) external returns (bool) {
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
// --- Mint/Burn ---
function mint(address to, uint256 value) public virtual auth {
require(to != address(0) && to != address(this), "ERC20/invalid-address");
unchecked {
// We don't need an overflow check here b/c balances[to] <= totalSupply
// and there is an overflow check below
_setBalance(to, _balanceOf(to) + value);
}
totalSupply = totalSupply + value;
emit Transfer(address(0), to, value);
}
function burn(address from, uint256 value) public virtual auth {
uint256 balance = balanceOf(from);
require(balance >= value, "ERC20/insufficient-balance");
if (from != msg.sender) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) {
require(allowed >= value, "ERC20/insufficient-allowance");
unchecked {
allowance[from][msg.sender] = allowed - value;
}
}
}
unchecked {
// We don't need overflow checks b/c require(balance >= value) and balance <= totalSupply
_setBalance(from, _balanceOf(from) - value);
totalSupply = totalSupply - value;
}
emit Transfer(from, address(0), value);
}
// --- Approve by signature ---
function permit(address owner, address spender, uint256 value, uint256 deadline, bytes memory signature) public {
require(block.timestamp <= deadline, "ERC20/permit-expired");
uint256 nonce;
unchecked {
nonce = nonces[owner]++;
}
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonce, deadline))
)
);
require(SignatureLib.isValidSignature(owner, digest, signature), "ERC20/invalid-permit");
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
/// @inheritdoc IERC20Permit
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external
{
permit(owner, spender, value, deadline, abi.encodePacked(r, s, v));
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;
/// @title IERC20
/// @dev Interface of the ERC20 standard as defined in the EIP.
/// @author Modified from OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
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);
}
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
interface IERC20Wrapper {
/**
* @dev Returns the address of the underlying ERC-20 token that is being wrapped.
*/
function underlying() external view returns (address);
/**
* @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.
*/
function depositFor(address account, uint256 value) external returns (bool);
/**
* @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.
*/
function withdrawTo(address account, uint256 value) external returns (bool);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;
import {IERC165} from "src/interfaces/IERC7575.sol";
struct HookData {
bytes16 from;
bytes16 to;
}
uint8 constant SUCCESS_CODE_ID = 0;
string constant SUCCESS_MESSAGE = "transfer-allowed";
uint8 constant ERROR_CODE_ID = 1;
string constant ERROR_MESSAGE = "transfer-blocked";
interface IHook is IERC165 {
/// @notice Callback on standard ERC20 transfer.
/// @dev MUST return bytes4(keccak256("onERC20Transfer(address,address,uint256,(bytes16,bytes16))"))
/// if successful
function onERC20Transfer(address from, address to, uint256 value, HookData calldata hookdata)
external
returns (bytes4);
/// @notice Callback on authorized ERC20 transfer.
/// @dev MUST return bytes4(keccak256("onERC20AuthTransfer(address,address,address,uint256,(bytes16,bytes16))"))
/// if successful
function onERC20AuthTransfer(address sender, address from, address to, uint256 value, HookData calldata hookdata)
external
returns (bytes4);
/// @notice Check if given transfer can be performed
function checkERC20Transfer(address from, address to, uint256 value, HookData calldata hookData)
external
view
returns (bool);
/// @notice Update a set of restriction for a token
/// @dev MAY be user specific, which would be included in the encoded `update` value
function updateRestriction(address token, bytes memory update) external;
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others.
*/
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[EIP 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);
}
interface IERC7575 is IERC165 {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the address of the share token
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function share() external view returns (address shareTokenAddress);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the total amount of the underlying asset that is “managed” by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}
interface IERC7575Share is IERC165 {
event VaultUpdate(address indexed asset, address vault);
/**
* @dev Returns the address of the Vault for the given asset.
*
* @param asset the ERC-20 token to deposit with into the Vault
*/
function vault(address asset) external view returns (address);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;
import {IERC20Metadata} from "src/interfaces/IERC20.sol";
import {IERC7575Share} from "src/interfaces/IERC7575.sol";
interface IERC1404 {
/// @notice Detects if a transfer will be reverted and if so returns an appropriate reference code
/// @param from Sending address
/// @param to Receiving address
/// @param value Amount of tokens being transferred
/// @return Code by which to reference message for rejection reasoning
/// @dev Overwrite with your custom transfer restriction logic
function detectTransferRestriction(address from, address to, uint256 value) external view returns (uint8);
/// @notice Returns a human-readable message for a given restriction code
/// @param restrictionCode Identifier for looking up a message
/// @return Text showing the restriction's reasoning
/// @dev Overwrite with your custom message and restrictionCode handling
function messageForTransferRestriction(uint8 restrictionCode) external view returns (string memory);
}
interface ITranche is IERC20Metadata, IERC7575Share, IERC1404 {
// --- Events ---
event File(bytes32 indexed what, address data);
event SetHookData(address indexed user, bytes16 data);
struct Balance {
/// @dev The user balance is limited to uint128. This is safe because the decimals are limited to 18,
/// thus the max balance is 2^128-1 / 10**18 = 3.40 * 10**20. This is also enforced on mint.
uint128 amount;
/// @dev There are 16 bytes that are used to store hook data (e.g. restrictions for users).
bytes16 hookData;
}
// --- Administration ---
/// @notice returns the hook that transfers perform callbacks to
/// @dev MUST comply to `IHook` interface
function hook() external view returns (address);
/// @notice Updates a contract parameter
/// @param what Accepts a bytes32 representation of 'name', 'symbol'
function file(bytes32 what, string memory data) external;
/// @notice Updates a contract parameter
/// @param what Accepts a bytes32 representation of 'hook'
function file(bytes32 what, address data) external;
/// @notice updates the vault for a given `asset`
function updateVault(address asset, address vault_) external;
// --- ERC20 overrides ---
/// @notice returns the 16 byte hook data of the given `user`.
/// @dev Stored in the 128 most significant bits of the user balance
function hookDataOf(address user) external view returns (bytes16);
/// @notice update the 16 byte hook data of the given `user`
function setHookData(address user, bytes16 hookData) external;
/// @notice Function to mint tokens
function mint(address user, uint256 value) external;
/// @notice Function to burn tokens
function burn(address user, uint256 value) external;
/// @notice Checks if the tokens can be transferred given the input values
function checkTransferRestriction(address from, address to, uint256 value) external view returns (bool);
/// @notice Performs an authorized transfer, with `sender` as the given sender.
/// @dev Requires allowance if `sender` != `from`
function authTransferFrom(address sender, address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;
/// @title Math Lib
/// @dev Standard math utilities missing in the Solidity language.
/// @author Modified from OpenZeppelin Contracts v4.9.3 (utils/math/Math.sol)
library MathLib {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/// @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
/// denominator == 0
/// @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
/// with further edits by Uniswap Labs also under MIT license.
// slither-disable-start divide-before-multiply
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator.
// Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
// works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
// slither-disable-end divide-before-multiply
/// @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/// @notice Safe type conversion from uint256 to uint8.
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert("MathLib/uint8-overflow");
}
return uint8(value);
}
/// @notice Safe type conversion from uint256 to uint128.
function toUint128(uint256 _value) internal pure returns (uint128 value) {
if (_value > type(uint128).max) {
revert("MathLib/uint128-overflow");
} else {
value = uint128(_value);
}
}
/// @notice Returns the smallest of two numbers.
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? b : a;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;
import {IAuth} from "src/interfaces/IAuth.sol";
/// @title Auth
/// @notice Simple authentication pattern
/// @author Based on code from https://github.com/makerdao/dss
abstract contract Auth is IAuth {
/// @inheritdoc IAuth
mapping(address => uint256) public wards;
constructor(address initialWard) {
wards[initialWard] = 1;
emit Rely(initialWard);
}
/// @dev Check if the msg.sender has permissions
modifier auth() {
require(wards[msg.sender] == 1, "Auth/not-authorized");
_;
}
/// @inheritdoc IAuth
function rely(address user) external auth {
wards[user] = 1;
emit Rely(user);
}
/// @inheritdoc IAuth
function deny(address user) external auth {
wards[user] = 0;
emit Deny(user);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;
/// @title EIP712 Lib
library EIP712Lib {
// keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
bytes32 public constant EIP712_DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
function calculateDomainSeparator(bytes32 nameHash, bytes32 versionHash) internal view returns (bytes32) {
return keccak256(abi.encode(EIP712_DOMAIN_TYPEHASH, nameHash, versionHash, block.chainid, address(this)));
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;
interface IERC1271 {
function isValidSignature(bytes32, bytes memory) external view returns (bytes4);
}
/// @title Signature Lib
library SignatureLib {
function isValidSignature(address signer, bytes32 digest, bytes memory signature)
internal
view
returns (bool valid)
{
require(signer != address(0), "SignatureLib/invalid-signer");
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
if (signer == ecrecover(digest, v, r, s)) {
return true;
}
}
if (signer.code.length > 0) {
(bool success, bytes memory result) =
signer.staticcall(abi.encodeCall(IERC1271.isValidSignature, (digest, signature)));
valid =
(success && result.length == 32 && abi.decode(result, (bytes4)) == IERC1271.isValidSignature.selector);
}
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;
interface IAuth {
event Rely(address indexed user);
event Deny(address indexed user);
/// @notice Returns whether the target is a ward (has admin access)
function wards(address target) external view returns (uint256);
/// @notice Make user a ward (give them admin access)
function rely(address user) external;
/// @notice Remove user as a ward (remove admin access)
function deny(address user) external;
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"@chimera/=lib/chimera/src/",
"chimera/=lib/chimera/src/",
"ds-test/=lib/chimera/lib/forge-std/lib/ds-test/src/"
],
"optimizer": {
"enabled": true,
"runs": 500
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint8","name":"decimals_","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Deny","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"address","name":"data","type":"address"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"string","name":"data","type":"string"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Rely","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bytes16","name":"data","type":"bytes16"}],"name":"SetHookData","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"address","name":"vault","type":"address"}],"name":"VaultUpdate","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"authTransferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"checkTransferRestriction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"deny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deploymentChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"detectTransferRestriction","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"string","name":"data","type":"string"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"hook","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"hookDataOf","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"restrictionCode","type":"uint8"}],"name":"messageForTransferRestriction","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"rely","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes16","name":"hookData","type":"bytes16"}],"name":"setHookData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"vault_","type":"address"}],"name":"updateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
610120604052348015610010575f80fd5b5060405161269338038061269383398101604081905261002f9161015f565b335f81815260208190526040808220600190555183929182917fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a25060ff166080908152604080518082018252600a81526943656e7472696675676560b01b6020918201527fe416b338a274162320c79445ae6604141d1cb08275eb27011b69f002dc094d0560a09081528251808401845260018152603160f81b908301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660c08181524660e0819052835186517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818801528088019190915260608101939093529582019590955230818301528351808203909201825290930190915281519101206101005250610186565b5f6020828403121561016f575f80fd5b815160ff8116811461017f575f80fd5b9392505050565b60805160a05160c05160e051610100516124c96101ca5f395f61087f01525f818161042901526107b301525f61082e01525f61080901525f6102b901526124c95ff3fe608060405234801561000f575f80fd5b50600436106101e7575f3560e01c80637f5a7c7b11610109578063cd0d00961161009e578063dd62ed3e1161006e578063dd62ed3e14610484578063e8e6dc75146104ae578063f815c03d146104f9578063fa1e713014610521575f80fd5b8063cd0d009614610424578063d4ce14151461044b578063d4e8be831461045e578063d505accf14610471575f80fd5b80639dc29fac116100d95780639dc29fac146103cc5780639fd5a6cf146103df578063a9059cbb146103f2578063bf353dbb14610405575f80fd5b80637f5a7c7b14610373578063887ca2491461039e57806395d89b41146103b15780639c52a7f1146103b9575f80fd5b8063313ce5671161017f5780636a9154aa1161014f5780636a9154aa1461031b57806370a082311461032e5780637ecebe00146103415780637f4ab1dd14610360575f80fd5b8063313ce567146102b45780633644e515146102ed57806340c10f19146102f557806365fae35e14610308575f80fd5b806318160ddd116101ba57806318160ddd146102505780631b451d281461026757806323b872dd1461027a57806330adf81f1461028d575f80fd5b806301ffc9a7146101eb57806306fdde0314610213578063095ea7b314610228578063097ac46e1461023b575b5f80fd5b6101fe6101f9366004611e7f565b610534565b60405190151581526020015b60405180910390f35b61021b61056a565b60405161020a9190611ec8565b6101fe610236366004611ef0565b6105f6565b61024e610249366004611fa3565b610661565b005b61025960035481565b60405190815260200161020a565b61024e610275366004611ffa565b6106c8565b6101fe61028836600461202b565b610790565b6102597f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102db7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161020a565b6102596107b0565b61024e610303366004611ef0565b6108a1565b61024e610316366004612065565b61090f565b61024e61032936600461207e565b6109a7565b61025961033c366004612065565b610a85565b61025961034f366004612065565b60066020525f908152604090205481565b61021b61036e3660046120cf565b610aab565b600854610386906001600160a01b031681565b6040516001600160a01b03909116815260200161020a565b6101fe6103ac3660046120e8565b610b2a565b61021b610cff565b61024e6103c7366004612065565b610d0c565b61024e6103da366004611ef0565b610da3565b61024e6103ed366004612130565b610db8565b6101fe610400366004611ef0565b610f9d565b610259610413366004612065565b5f6020819052908152604090205481565b6102597f000000000000000000000000000000000000000000000000000000000000000081565b6102db61045936600461202b565b610fb5565b61024e61046c3660046121b0565b6110e1565b61024e61047f3660046121d1565b611212565b610259610492366004611ffa565b600560209081525f928352604080842090915290825290205481565b6104e06104bc366004612065565b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6040516001600160801b0319909116815260200161020a565b610386610507366004612065565b60096020525f90815260409020546001600160a01b031681565b6101fe61052f36600461202b565b611281565b5f6001600160e01b0319821663f815c03d60e01b148061056457506001600160e01b031982166301ffc9a760e01b145b92915050565b6001805461057790612237565b80601f01602080910402602001604051908101604052809291908181526020018280546105a390612237565b80156105ee5780601f106105c5576101008083540402835291602001916105ee565b820191905f5260205f20905b8154815290600101906020018083116105d157829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106509086815260200190565b60405180910390a350600192915050565b335f908152602081905260409020546001146106ba5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064015b60405180910390fd5b6106c4828261129a565b5050565b335f9081526020819052604090205460011461071c5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b038281165f81815260096020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19169486169485179055905192835290917fd8c6b8f6ca4977137bd0c05f8e49099e0bbbefe5ed3010bf828a76dbab95831391015b60405180910390a25050565b5f61079c8484846113a2565b90506107a98484846113af565b9392505050565b5f7f0000000000000000000000000000000000000000000000000000000000000000461461087c5750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6108ab828261151b565b6003546001600160801b0310156109045760405162461bcd60e51b815260206004820152601a60248201527f5472616e6368652f657863656564732d6d61782d737570706c7900000000000060448201526064016106b1565b6106c45f83836113af565b335f908152602081905260409020546001146109635760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f8181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b335f90815260208190526040902054600114806109ce57506008546001600160a01b031633145b610a1a5760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b6001600160a01b0382165f8181526007602090815260409182902080546001600160801b0316600160801b608087901c0217905590516001600160801b0319841681527f8fa29948e0a84e3c738d2e921e65fab6e5a02291fe898fd94d60c3c8ee614c459101610784565b6001600160a01b0381165f908152600760205260408120546001600160801b0316610564565b606060ff821615610af1576040518060400160405280601081526020017f7472616e736665722d626c6f636b656400000000000000000000000000000000815250610564565b505060408051808201909152601081527f7472616e736665722d616c6c6f77656400000000000000000000000000000000602082015290565b335f90815260208190526040812054600114610b7e5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b610b8a8585858561165b565b6008549091506001600160a01b03161580610cab57506008546040805180820190915263078d18cd60e01b916001600160a01b03169063078d18cd90889088908890889080610bf7856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b0319168152602001610c2e8c6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e088901b168152610c5f95949392919060040161226f565b6020604051808303815f875af1158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f91906122ba565b6001600160e01b031916145b610cf75760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b949350505050565b6002805461057790612237565b335f90815260208190526040902054600114610d605760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f81815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b610dad8282611896565b6106c4825f836113af565b81421115610e085760405162461bcd60e51b815260206004820152601460248201527f45524332302f7065726d69742d6578706972656400000000000000000000000060448201526064016106b1565b6001600160a01b0385165f90815260066020526040812080546001810190915590610e316107b0565b604080517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960208201526001600160a01b03808b169282019290925290881660608201526080810187905260a0810184905260c0810186905260e00160405160208183030381529060405280519060200120604051602001610eca92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050610eed878285611a75565b610f395760405162461bcd60e51b815260206004820152601460248201527f45524332302f696e76616c69642d7065726d697400000000000000000000000060448201526064016106b1565b6001600160a01b038781165f818152600560209081526040808320948b168084529482529182902089905590518881527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b5f610fa88383611c68565b90506105643384846113af565b6008545f906001600160a01b0316610fce57505f6107a9565b60085f9054906101000a90046001600160a01b03166001600160a01b031663ef59bc9285858560405180604001604052806110278b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161105e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261108e94939291906004016122d5565b602060405180830381865afa1580156110a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110cd9190612321565b6110d8576001610cf7565b5f949350505050565b335f908152602081905260409020546001148061110857506008546001600160a01b031633145b6111545760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b8163686f6f6b60e01b0361118f576008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383161790556111d7565b60405162461bcd60e51b815260206004820152601f60248201527f5472616e6368652f66696c652d756e7265636f676e697a65642d706172616d0060448201526064016106b1565b6040516001600160a01b038216815282907f8fef588b5fc1afbf5b2f06c1a435d513f208da2e6704c3d8f0e0ec91167066ba90602001610784565b6112788787878786868960405160200161126493929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052610db8565b50505050505050565b5f8061128e858585610fb5565b60ff1614949350505050565b335f908152602081905260409020546001146112ee5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b81636e616d6560e01b0361130e576001611308828261238b565b50611372565b81651cde5b589bdb60d21b0361132a576002611308828261238b565b60405162461bcd60e51b815260206004820152601d60248201527f45524332302f66696c652d756e7265636f676e697a65642d706172616d00000060448201526064016106b1565b817fe42e0b9a029dc87ccb1029c632e6359090acd0eb032b2b59c811e3ec70160dc6826040516107849190611ec8565b5f610cf73385858561165b565b6008546001600160a01b031615806114ca575060085460408051808201909152631fb8c88760e11b916001600160a01b031690633f71910e9086908690869080611417856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161144e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261147e94939291906004016122d5565b6020604051808303815f875af115801561149a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114be91906122ba565b6001600160e01b031916145b6115165760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b505050565b335f9081526020819052604090205460011461156f5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0382161580159061159057506001600160a01b0382163014155b6115d45760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b6116068282611600856001600160a01b03165f908152600760205260409020546001600160801b031690565b01611dc4565b806003546116149190612446565b6003556040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b5f6001600160a01b0383161580159061167d57506001600160a01b0383163014155b6116c15760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f6116cb85610a85565b90508281101561171d5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b856001600160a01b0316856001600160a01b0316146117df576001600160a01b038086165f908152600560209081526040808320938a16835292905220545f1981146117dd57838110156117b35760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b038087165f908152600560209081526040808320938b1683529290522084820390555b505b611811858461180b886001600160a01b03165f908152600760205260409020546001600160801b031690565b03611dc4565b61183d8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161188291815260200190565b60405180910390a350600195945050505050565b335f908152602081905260409020546001146118ea5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b5f6118f483610a85565b9050818110156119465760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b6001600160a01b03831633146119fb576001600160a01b0383165f9081526005602090815260408083203384529091529020545f1981146119f957828110156119d15760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b0384165f908152600560209081526040808320338452909152902083820390555b505b611a27838361180b866001600160a01b03165f908152600760205260409020546001600160801b031690565b6003805483900390556040518281525f906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b5f6001600160a01b038416611acc5760405162461bcd60e51b815260206004820152601b60248201527f5369676e61747572654c69622f696e76616c69642d7369676e6572000000000060448201526064016106b1565b8151604103611b645760208281015160408085015160608087015183515f8082529681018086528a9052951a928501839052840183905260808401819052919260019060a0016020604051602081039080840390855afa158015611b32573d5f803e3d5ffd5b505050602060405103516001600160a01b0316876001600160a01b031603611b6057600193505050506107a9565b5050505b6001600160a01b0384163b156107a9575f80856001600160a01b03168585604051602401611b93929190612465565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b135d3f60e11b17905251611bdd919061247d565b5f60405180830381855afa9150503d805f8114611c15576040519150601f19603f3d011682016040523d82523d5f602084013e611c1a565b606091505b5091509150818015611c2d575080516020145b8015611c5e57508051630b135d3f60e11b90611c5290830160209081019084016122ba565b6001600160e01b031916145b9695505050505050565b5f6001600160a01b03831615801590611c8a57506001600160a01b0383163014155b611cce5760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f611cd833610a85565b905082811015611d2a5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b335f81815260076020526040902054611d4e919085906001600160801b031661180b565b611d7a8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b6040518381526001600160a01b0385169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35060019392505050565b611dcd81611e07565b6001600160a01b03929092165f90815260076020526040902080546001600160801b0319166001600160801b039093169290921790915550565b5f6001600160801b03821115611e5f5760405162461bcd60e51b815260206004820152601860248201527f4d6174684c69622f75696e743132382d6f766572666c6f77000000000000000060448201526064016106b1565b50805b919050565b6001600160e01b031981168114611e7c575f80fd5b50565b5f60208284031215611e8f575f80fd5b81356107a981611e67565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6107a96020830184611e9a565b80356001600160a01b0381168114611e62575f80fd5b5f8060408385031215611f01575f80fd5b611f0a83611eda565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f8067ffffffffffffffff841115611f4657611f46611f18565b50604051601f19601f85018116603f0116810181811067ffffffffffffffff82111715611f7557611f75611f18565b604052838152905080828401851015611f8c575f80fd5b838360208301375f60208583010152509392505050565b5f8060408385031215611fb4575f80fd5b82359150602083013567ffffffffffffffff811115611fd1575f80fd5b8301601f81018513611fe1575f80fd5b611ff085823560208401611f2c565b9150509250929050565b5f806040838503121561200b575f80fd5b61201483611eda565b915061202260208401611eda565b90509250929050565b5f805f6060848603121561203d575f80fd5b61204684611eda565b925061205460208501611eda565b929592945050506040919091013590565b5f60208284031215612075575f80fd5b6107a982611eda565b5f806040838503121561208f575f80fd5b61209883611eda565b915060208301356001600160801b0319811681146120b4575f80fd5b809150509250929050565b803560ff81168114611e62575f80fd5b5f602082840312156120df575f80fd5b6107a9826120bf565b5f805f80608085870312156120fb575f80fd5b61210485611eda565b935061211260208601611eda565b925061212060408601611eda565b9396929550929360600135925050565b5f805f805f60a08688031215612144575f80fd5b61214d86611eda565b945061215b60208701611eda565b93506040860135925060608601359150608086013567ffffffffffffffff811115612184575f80fd5b8601601f81018813612194575f80fd5b6121a388823560208401611f2c565b9150509295509295909350565b5f80604083850312156121c1575f80fd5b8235915061202260208401611eda565b5f805f805f805f60e0888a0312156121e7575f80fd5b6121f088611eda565b96506121fe60208901611eda565b9550604088013594506060880135935061221a608089016120bf565b9699959850939692959460a0840135945060c09093013592915050565b600181811c9082168061224b57607f821691505b60208210810361226957634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b0386811682528581166020830152841660408201526060810183905260c08101611c5e608083018480516001600160801b0319908116835260209182015116910152565b5f602082840312156122ca575f80fd5b81516107a981611e67565b6001600160a01b038581168252841660208201526040810183905260a08101612318606083018480516001600160801b0319908116835260209182015116910152565b95945050505050565b5f60208284031215612331575f80fd5b815180151581146107a9575f80fd5b601f82111561151657805f5260205f20601f840160051c810160208510156123655750805b601f840160051c820191505b81811015612384575f8155600101612371565b5050505050565b815167ffffffffffffffff8111156123a5576123a5611f18565b6123b9816123b38454612237565b84612340565b6020601f8211600181146123eb575f83156123d45750848201515b5f19600385901b1c1916600184901b178455612384565b5f84815260208120601f198516915b8281101561241a57878501518255602094850194600190920191016123fa565b508482101561243757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561056457634e487b7160e01b5f52601160045260245ffd5b828152604060208201525f610cf76040830184611e9a565b5f82518060208501845e5f92019182525091905056fea2646970667358221220d96788efce0abae761dd6fa9f185d3e7a99eb9ee0dcc47b2636aa6ead05be32564736f6c634300081a00330000000000000000000000000000000000000000000000000000000000000006
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101e7575f3560e01c80637f5a7c7b11610109578063cd0d00961161009e578063dd62ed3e1161006e578063dd62ed3e14610484578063e8e6dc75146104ae578063f815c03d146104f9578063fa1e713014610521575f80fd5b8063cd0d009614610424578063d4ce14151461044b578063d4e8be831461045e578063d505accf14610471575f80fd5b80639dc29fac116100d95780639dc29fac146103cc5780639fd5a6cf146103df578063a9059cbb146103f2578063bf353dbb14610405575f80fd5b80637f5a7c7b14610373578063887ca2491461039e57806395d89b41146103b15780639c52a7f1146103b9575f80fd5b8063313ce5671161017f5780636a9154aa1161014f5780636a9154aa1461031b57806370a082311461032e5780637ecebe00146103415780637f4ab1dd14610360575f80fd5b8063313ce567146102b45780633644e515146102ed57806340c10f19146102f557806365fae35e14610308575f80fd5b806318160ddd116101ba57806318160ddd146102505780631b451d281461026757806323b872dd1461027a57806330adf81f1461028d575f80fd5b806301ffc9a7146101eb57806306fdde0314610213578063095ea7b314610228578063097ac46e1461023b575b5f80fd5b6101fe6101f9366004611e7f565b610534565b60405190151581526020015b60405180910390f35b61021b61056a565b60405161020a9190611ec8565b6101fe610236366004611ef0565b6105f6565b61024e610249366004611fa3565b610661565b005b61025960035481565b60405190815260200161020a565b61024e610275366004611ffa565b6106c8565b6101fe61028836600461202b565b610790565b6102597f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102db7f000000000000000000000000000000000000000000000000000000000000000681565b60405160ff909116815260200161020a565b6102596107b0565b61024e610303366004611ef0565b6108a1565b61024e610316366004612065565b61090f565b61024e61032936600461207e565b6109a7565b61025961033c366004612065565b610a85565b61025961034f366004612065565b60066020525f908152604090205481565b61021b61036e3660046120cf565b610aab565b600854610386906001600160a01b031681565b6040516001600160a01b03909116815260200161020a565b6101fe6103ac3660046120e8565b610b2a565b61021b610cff565b61024e6103c7366004612065565b610d0c565b61024e6103da366004611ef0565b610da3565b61024e6103ed366004612130565b610db8565b6101fe610400366004611ef0565b610f9d565b610259610413366004612065565b5f6020819052908152604090205481565b6102597f000000000000000000000000000000000000000000000000000000000000000181565b6102db61045936600461202b565b610fb5565b61024e61046c3660046121b0565b6110e1565b61024e61047f3660046121d1565b611212565b610259610492366004611ffa565b600560209081525f928352604080842090915290825290205481565b6104e06104bc366004612065565b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6040516001600160801b0319909116815260200161020a565b610386610507366004612065565b60096020525f90815260409020546001600160a01b031681565b6101fe61052f36600461202b565b611281565b5f6001600160e01b0319821663f815c03d60e01b148061056457506001600160e01b031982166301ffc9a760e01b145b92915050565b6001805461057790612237565b80601f01602080910402602001604051908101604052809291908181526020018280546105a390612237565b80156105ee5780601f106105c5576101008083540402835291602001916105ee565b820191905f5260205f20905b8154815290600101906020018083116105d157829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106509086815260200190565b60405180910390a350600192915050565b335f908152602081905260409020546001146106ba5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064015b60405180910390fd5b6106c4828261129a565b5050565b335f9081526020819052604090205460011461071c5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b038281165f81815260096020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19169486169485179055905192835290917fd8c6b8f6ca4977137bd0c05f8e49099e0bbbefe5ed3010bf828a76dbab95831391015b60405180910390a25050565b5f61079c8484846113a2565b90506107a98484846113af565b9392505050565b5f7f0000000000000000000000000000000000000000000000000000000000000001461461087c5750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527fe416b338a274162320c79445ae6604141d1cb08275eb27011b69f002dc094d05828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b507f8667ee870ef3dcdf8808b2356deae1401df3c16339f40708ab8c44616712591390565b6108ab828261151b565b6003546001600160801b0310156109045760405162461bcd60e51b815260206004820152601a60248201527f5472616e6368652f657863656564732d6d61782d737570706c7900000000000060448201526064016106b1565b6106c45f83836113af565b335f908152602081905260409020546001146109635760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f8181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b335f90815260208190526040902054600114806109ce57506008546001600160a01b031633145b610a1a5760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b6001600160a01b0382165f8181526007602090815260409182902080546001600160801b0316600160801b608087901c0217905590516001600160801b0319841681527f8fa29948e0a84e3c738d2e921e65fab6e5a02291fe898fd94d60c3c8ee614c459101610784565b6001600160a01b0381165f908152600760205260408120546001600160801b0316610564565b606060ff821615610af1576040518060400160405280601081526020017f7472616e736665722d626c6f636b656400000000000000000000000000000000815250610564565b505060408051808201909152601081527f7472616e736665722d616c6c6f77656400000000000000000000000000000000602082015290565b335f90815260208190526040812054600114610b7e5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b610b8a8585858561165b565b6008549091506001600160a01b03161580610cab57506008546040805180820190915263078d18cd60e01b916001600160a01b03169063078d18cd90889088908890889080610bf7856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b0319168152602001610c2e8c6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e088901b168152610c5f95949392919060040161226f565b6020604051808303815f875af1158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f91906122ba565b6001600160e01b031916145b610cf75760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b949350505050565b6002805461057790612237565b335f90815260208190526040902054600114610d605760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f81815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b610dad8282611896565b6106c4825f836113af565b81421115610e085760405162461bcd60e51b815260206004820152601460248201527f45524332302f7065726d69742d6578706972656400000000000000000000000060448201526064016106b1565b6001600160a01b0385165f90815260066020526040812080546001810190915590610e316107b0565b604080517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960208201526001600160a01b03808b169282019290925290881660608201526080810187905260a0810184905260c0810186905260e00160405160208183030381529060405280519060200120604051602001610eca92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050610eed878285611a75565b610f395760405162461bcd60e51b815260206004820152601460248201527f45524332302f696e76616c69642d7065726d697400000000000000000000000060448201526064016106b1565b6001600160a01b038781165f818152600560209081526040808320948b168084529482529182902089905590518881527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b5f610fa88383611c68565b90506105643384846113af565b6008545f906001600160a01b0316610fce57505f6107a9565b60085f9054906101000a90046001600160a01b03166001600160a01b031663ef59bc9285858560405180604001604052806110278b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161105e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261108e94939291906004016122d5565b602060405180830381865afa1580156110a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110cd9190612321565b6110d8576001610cf7565b5f949350505050565b335f908152602081905260409020546001148061110857506008546001600160a01b031633145b6111545760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b8163686f6f6b60e01b0361118f576008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383161790556111d7565b60405162461bcd60e51b815260206004820152601f60248201527f5472616e6368652f66696c652d756e7265636f676e697a65642d706172616d0060448201526064016106b1565b6040516001600160a01b038216815282907f8fef588b5fc1afbf5b2f06c1a435d513f208da2e6704c3d8f0e0ec91167066ba90602001610784565b6112788787878786868960405160200161126493929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052610db8565b50505050505050565b5f8061128e858585610fb5565b60ff1614949350505050565b335f908152602081905260409020546001146112ee5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b81636e616d6560e01b0361130e576001611308828261238b565b50611372565b81651cde5b589bdb60d21b0361132a576002611308828261238b565b60405162461bcd60e51b815260206004820152601d60248201527f45524332302f66696c652d756e7265636f676e697a65642d706172616d00000060448201526064016106b1565b817fe42e0b9a029dc87ccb1029c632e6359090acd0eb032b2b59c811e3ec70160dc6826040516107849190611ec8565b5f610cf73385858561165b565b6008546001600160a01b031615806114ca575060085460408051808201909152631fb8c88760e11b916001600160a01b031690633f71910e9086908690869080611417856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161144e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261147e94939291906004016122d5565b6020604051808303815f875af115801561149a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114be91906122ba565b6001600160e01b031916145b6115165760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b505050565b335f9081526020819052604090205460011461156f5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0382161580159061159057506001600160a01b0382163014155b6115d45760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b6116068282611600856001600160a01b03165f908152600760205260409020546001600160801b031690565b01611dc4565b806003546116149190612446565b6003556040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b5f6001600160a01b0383161580159061167d57506001600160a01b0383163014155b6116c15760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f6116cb85610a85565b90508281101561171d5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b856001600160a01b0316856001600160a01b0316146117df576001600160a01b038086165f908152600560209081526040808320938a16835292905220545f1981146117dd57838110156117b35760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b038087165f908152600560209081526040808320938b1683529290522084820390555b505b611811858461180b886001600160a01b03165f908152600760205260409020546001600160801b031690565b03611dc4565b61183d8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161188291815260200190565b60405180910390a350600195945050505050565b335f908152602081905260409020546001146118ea5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b5f6118f483610a85565b9050818110156119465760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b6001600160a01b03831633146119fb576001600160a01b0383165f9081526005602090815260408083203384529091529020545f1981146119f957828110156119d15760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b0384165f908152600560209081526040808320338452909152902083820390555b505b611a27838361180b866001600160a01b03165f908152600760205260409020546001600160801b031690565b6003805483900390556040518281525f906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b5f6001600160a01b038416611acc5760405162461bcd60e51b815260206004820152601b60248201527f5369676e61747572654c69622f696e76616c69642d7369676e6572000000000060448201526064016106b1565b8151604103611b645760208281015160408085015160608087015183515f8082529681018086528a9052951a928501839052840183905260808401819052919260019060a0016020604051602081039080840390855afa158015611b32573d5f803e3d5ffd5b505050602060405103516001600160a01b0316876001600160a01b031603611b6057600193505050506107a9565b5050505b6001600160a01b0384163b156107a9575f80856001600160a01b03168585604051602401611b93929190612465565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b135d3f60e11b17905251611bdd919061247d565b5f60405180830381855afa9150503d805f8114611c15576040519150601f19603f3d011682016040523d82523d5f602084013e611c1a565b606091505b5091509150818015611c2d575080516020145b8015611c5e57508051630b135d3f60e11b90611c5290830160209081019084016122ba565b6001600160e01b031916145b9695505050505050565b5f6001600160a01b03831615801590611c8a57506001600160a01b0383163014155b611cce5760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f611cd833610a85565b905082811015611d2a5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b335f81815260076020526040902054611d4e919085906001600160801b031661180b565b611d7a8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b6040518381526001600160a01b0385169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35060019392505050565b611dcd81611e07565b6001600160a01b03929092165f90815260076020526040902080546001600160801b0319166001600160801b039093169290921790915550565b5f6001600160801b03821115611e5f5760405162461bcd60e51b815260206004820152601860248201527f4d6174684c69622f75696e743132382d6f766572666c6f77000000000000000060448201526064016106b1565b50805b919050565b6001600160e01b031981168114611e7c575f80fd5b50565b5f60208284031215611e8f575f80fd5b81356107a981611e67565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6107a96020830184611e9a565b80356001600160a01b0381168114611e62575f80fd5b5f8060408385031215611f01575f80fd5b611f0a83611eda565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f8067ffffffffffffffff841115611f4657611f46611f18565b50604051601f19601f85018116603f0116810181811067ffffffffffffffff82111715611f7557611f75611f18565b604052838152905080828401851015611f8c575f80fd5b838360208301375f60208583010152509392505050565b5f8060408385031215611fb4575f80fd5b82359150602083013567ffffffffffffffff811115611fd1575f80fd5b8301601f81018513611fe1575f80fd5b611ff085823560208401611f2c565b9150509250929050565b5f806040838503121561200b575f80fd5b61201483611eda565b915061202260208401611eda565b90509250929050565b5f805f6060848603121561203d575f80fd5b61204684611eda565b925061205460208501611eda565b929592945050506040919091013590565b5f60208284031215612075575f80fd5b6107a982611eda565b5f806040838503121561208f575f80fd5b61209883611eda565b915060208301356001600160801b0319811681146120b4575f80fd5b809150509250929050565b803560ff81168114611e62575f80fd5b5f602082840312156120df575f80fd5b6107a9826120bf565b5f805f80608085870312156120fb575f80fd5b61210485611eda565b935061211260208601611eda565b925061212060408601611eda565b9396929550929360600135925050565b5f805f805f60a08688031215612144575f80fd5b61214d86611eda565b945061215b60208701611eda565b93506040860135925060608601359150608086013567ffffffffffffffff811115612184575f80fd5b8601601f81018813612194575f80fd5b6121a388823560208401611f2c565b9150509295509295909350565b5f80604083850312156121c1575f80fd5b8235915061202260208401611eda565b5f805f805f805f60e0888a0312156121e7575f80fd5b6121f088611eda565b96506121fe60208901611eda565b9550604088013594506060880135935061221a608089016120bf565b9699959850939692959460a0840135945060c09093013592915050565b600181811c9082168061224b57607f821691505b60208210810361226957634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b0386811682528581166020830152841660408201526060810183905260c08101611c5e608083018480516001600160801b0319908116835260209182015116910152565b5f602082840312156122ca575f80fd5b81516107a981611e67565b6001600160a01b038581168252841660208201526040810183905260a08101612318606083018480516001600160801b0319908116835260209182015116910152565b95945050505050565b5f60208284031215612331575f80fd5b815180151581146107a9575f80fd5b601f82111561151657805f5260205f20601f840160051c810160208510156123655750805b601f840160051c820191505b81811015612384575f8155600101612371565b5050505050565b815167ffffffffffffffff8111156123a5576123a5611f18565b6123b9816123b38454612237565b84612340565b6020601f8211600181146123eb575f83156123d45750848201515b5f19600385901b1c1916600184901b178455612384565b5f84815260208120601f198516915b8281101561241a57878501518255602094850194600190920191016123fa565b508482101561243757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561056457634e487b7160e01b5f52601160045260245ffd5b828152604060208201525f610cf76040830184611e9a565b5f82518060208501845e5f92019182525091905056fea2646970667358221220d96788efce0abae761dd6fa9f185d3e7a99eb9ee0dcc47b2636aa6ead05be32564736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000006
-----Decoded View---------------
Arg [0] : decimals_ (uint8): 6
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000006
Loading...
Loading
Loading...
Loading
OVERVIEW
Centrifuge is the pioneering platform for real-world asset tokenization. Through Centrifuge, investors gain access to a diverse range of assets, improving transparency and achieving better insight into their portfolio.Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.