Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 30834357 | 263 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TransferBlacklistHook
Compiler Version
v0.8.29+commit.ab55807c
Optimization Enabled:
Yes with 100000 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.29;
import { IChainalysisSanctionsOracle } from "src/dependencies/chainalysis/IChainalysisSanctionsOracle.sol";
import { AbstractTransferHook } from "src/periphery/hooks/transfer/AbstractTransferHook.sol";
import { IBeforeTransferHook } from "src/core/interfaces/IBeforeTransferHook.sol";
import { ITransferBlacklistHook } from "src/periphery/interfaces/hooks/transfer/ITransferBlacklistHook.sol";
/// @title TransferBlacklistHook
/// @notice Blocks users on a blacklist from transfering vault units in multi-depositor vaults
contract TransferBlacklistHook is AbstractTransferHook, ITransferBlacklistHook {
////////////////////////////////////////////////////////////
// Immutables //
////////////////////////////////////////////////////////////
/// @notice The blacklist oracle (using Chainalysis sanctions oracle interface)
IChainalysisSanctionsOracle public immutable BLACKLIST_ORACLE;
constructor(IChainalysisSanctionsOracle oracle_) {
// Requirements: check that the oracle is not the zero address
require(address(oracle_) != address(0), AeraPeriphery__ZeroAddressBlacklistOracle());
// Effects: set the blacklist oracle
BLACKLIST_ORACLE = oracle_;
}
////////////////////////////////////////////////////////////
// Public / External Functions //
////////////////////////////////////////////////////////////
/// @inheritdoc IBeforeTransferHook
function beforeTransfer(address from, address to, address transferAgent)
public
view
override(AbstractTransferHook, IBeforeTransferHook)
{
super.beforeTransfer(from, to, transferAgent);
// Check that the `from` and `to` addresses are not sanctioned
require(from == address(0) || !BLACKLIST_ORACLE.isSanctioned(from), AeraPeriphery__BlacklistedAddress(from));
require(to == address(0) || !BLACKLIST_ORACLE.isSanctioned(to), AeraPeriphery__BlacklistedAddress(to));
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.29;
interface IChainalysisSanctionsOracle {
////////////////////////////////////////////////////////////
// Functions //
////////////////////////////////////////////////////////////
/// @notice Check if an account is sanctioned
/// @param account The account to check
/// @return True if the account is sanctioned, false otherwise
function isSanctioned(address account) external view returns (bool);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.29;
import { VaultAuth } from "src/core/VaultAuth.sol";
import { IBeforeTransferHook } from "src/core/interfaces/IBeforeTransferHook.sol";
/// @title IBeforeTransferHook
/// @notice Used in multi-depositor vaults to control whether vault units can be transfered
/// Provides default functionality to disable unit transfers all together for all implementations
abstract contract AbstractTransferHook is IBeforeTransferHook, VaultAuth {
////////////////////////////////////////////////////////////
// Storage //
////////////////////////////////////////////////////////////
/// @notice Whether the vault units are transferable
mapping(address vault => bool isVaultUnitTransferable) public isVaultUnitTransferable;
////////////////////////////////////////////////////////////
// Public / External Functions //
////////////////////////////////////////////////////////////
/// @inheritdoc IBeforeTransferHook
function setIsVaultUnitsTransferable(address vault, bool isTransferable) external requiresVaultAuth(vault) {
_setIsVaultUnitsTransferable(vault, isTransferable);
}
/// @inheritdoc IBeforeTransferHook
function beforeTransfer(address from, address to, address transferAgent) public view virtual {
if (from != transferAgent && to != transferAgent && from != address(0) && to != address(0)) {
// Check that the vault units are transferable, if the operation is not mint/burn
require(isVaultUnitTransferable[msg.sender], Aera__VaultUnitsNotTransferable(msg.sender));
}
}
////////////////////////////////////////////////////////////
// Private / Internal Functions //
////////////////////////////////////////////////////////////
/// @notice Set the vault unit transferable status
/// @param vault The vault to set the transferable status for
/// @param isTransferable Whether the vault units are transferable
function _setIsVaultUnitsTransferable(address vault, bool isTransferable) internal {
// Effects: set the vault unit transferable status
isVaultUnitTransferable[vault] = isTransferable;
// Log the vault unit transferable status set
emit VaultUnitTransferableSet(vault, isTransferable);
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.29;
/// @title IBeforeTransferHook
/// @notice Interface for token transfer hooks used for vault units in multi-depositor vaults
interface IBeforeTransferHook {
////////////////////////////////////////////////////////////
// Events //
////////////////////////////////////////////////////////////
event VaultUnitTransferableSet(address indexed vault, bool isTransferable);
////////////////////////////////////////////////////////////
// Errors //
////////////////////////////////////////////////////////////
error Aera__NotVaultOwner();
error Aera__VaultUnitsNotTransferable(address vault);
////////////////////////////////////////////////////////////
// Functions //
////////////////////////////////////////////////////////////
/// @notice Set whether vault units should be transferable
/// @param vault The vault to update status for
/// @param isTransferable Whether the vault units are transferable
function setIsVaultUnitsTransferable(address vault, bool isTransferable) external;
/// @notice Perform before transfer checks
/// @param from Address that is sending the units
/// @param to Address that is receiving the units
/// @param transferAgent Address that is always allowed to transfer the units
function beforeTransfer(address from, address to, address transferAgent) external view;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.29;
import { IBeforeTransferHook } from "src/core/interfaces/IBeforeTransferHook.sol";
/// @title ITransferBlacklistHook
/// @notice Errors used in the transfer blacklist hook
interface ITransferBlacklistHook is IBeforeTransferHook {
////////////////////////////////////////////////////////////
// Errors //
////////////////////////////////////////////////////////////
error AeraPeriphery__BlacklistedAddress(address address_);
error AeraPeriphery__ZeroAddressBlacklistOracle();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.29;
import { Auth } from "@solmate/auth/Auth.sol";
/// @title VaultAuth
/// @notice Abstract contract that provides authorization check for vault operations
/// @dev Used by contracts that need to verify if a caller has permission to perform vault-specific actions. The
/// authorization can come from either being the vault owner or having explicit permission through the vault's authority
abstract contract VaultAuth {
////////////////////////////////////////////////////////////
// Errors //
////////////////////////////////////////////////////////////
error Aera__CallerIsNotAuthorized();
////////////////////////////////////////////////////////////
// Modifiers //
////////////////////////////////////////////////////////////
modifier requiresVaultAuth(address vault) {
// Requirements: check that the caller is either the vault owner or has permission to call the function
require(
msg.sender == Auth(vault).owner() || Auth(vault).authority().canCall(msg.sender, address(this), msg.sig),
Aera__CallerIsNotAuthorized()
);
_;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.29;
/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
event OwnershipTransferred(address indexed user, address indexed newOwner);
event AuthorityUpdated(address indexed user, Authority indexed newAuthority);
address public owner;
Authority public authority;
constructor(address _owner, Authority _authority) {
owner = _owner;
authority = _authority;
emit OwnershipTransferred(msg.sender, _owner);
emit AuthorityUpdated(msg.sender, _authority);
}
modifier requiresAuth() virtual {
require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");
_;
}
function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.
// Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
// aware that this makes protected functions uncallable even to the owner if the authority is out of order.
return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
}
function setAuthority(Authority newAuthority) public virtual {
// We check if the caller is the owner first because we want to ensure they can
// always swap out the authority even if it's reverting or using up a lot of gas.
require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));
authority = newAuthority;
emit AuthorityUpdated(msg.sender, newAuthority);
}
function transferOwnership(address newOwner) public virtual requiresAuth {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}
/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
function canCall(address user, address target, bytes4 functionSig) external view returns (bool);
}{
"remappings": [
"@oz/=lib/openzeppelin-contracts/contracts/",
"@solmate/=src/dependencies/solmate/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 100000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IChainalysisSanctionsOracle","name":"oracle_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"AeraPeriphery__BlacklistedAddress","type":"error"},{"inputs":[],"name":"AeraPeriphery__ZeroAddressBlacklistOracle","type":"error"},{"inputs":[],"name":"Aera__CallerIsNotAuthorized","type":"error"},{"inputs":[],"name":"Aera__NotVaultOwner","type":"error"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"Aera__VaultUnitsNotTransferable","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"bool","name":"isTransferable","type":"bool"}],"name":"VaultUnitTransferableSet","type":"event"},{"inputs":[],"name":"BLACKLIST_ORACLE","outputs":[{"internalType":"contract IChainalysisSanctionsOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"transferAgent","type":"address"}],"name":"beforeTransfer","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"isVaultUnitTransferable","outputs":[{"internalType":"bool","name":"isVaultUnitTransferable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"bool","name":"isTransferable","type":"bool"}],"name":"setIsVaultUnitsTransferable","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a03461008c57601f61086938819003918201601f19168301916001600160401b038311848410176100905780849260209460405283398101031261008c57516001600160a01b03811680820361008c571561007d576080526040516107c490816100a582396080518181816095015281816101df015261029d0152f35b6308e7625f60e11b5f5260045ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f35908160e01c91826370598155146103b957505080638359b8d214610352578063abd626b0146100bd5763bb923cec1461004b575f80fd5b346100b9575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b957602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5f80fd5b346100b95760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b9576100f46106c4565b60243573ffffffffffffffffffffffffffffffffffffffff8116918282036100b9576044359073ffffffffffffffffffffffffffffffffffffffff82168092036100b95773ffffffffffffffffffffffffffffffffffffffff811691808314159081610347575b508061033e575b80610335575b6102f6575b81158015610253575b610180925061076d565b81158015610195575b610193925061076d565b005b50604051917fdf592f7d000000000000000000000000000000000000000000000000000000008352600483015260208260248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa801561024857610193925f91610219575b5015610189565b61023b915060203d602011610241575b61023381836106e7565b810190610755565b83610212565b503d610229565b6040513d5f823e3d90fd5b50604051917fdf592f7d000000000000000000000000000000000000000000000000000000008352600483015260208260248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa801561024857610180925f916102d7575b5015610176565b6102f0915060203d6020116102415761023381836106e7565b856102d0565b335f525f60205260ff60405f20541661016d577f817720f8000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b50831515610168565b50811515610162565b90508414158561015b565b346100b95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b95773ffffffffffffffffffffffffffffffffffffffff61039e6106c4565b165f525f602052602060ff60405f2054166040519015158152f35b346100b95760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b9576103f06106c4565b90602435918215158093036100b95773ffffffffffffffffffffffffffffffffffffffff16927f8da5cb5b000000000000000000000000000000000000000000000000000000008152602081600481875afa8015610248575f90610661575b73ffffffffffffffffffffffffffffffffffffffff9150163314908115610501575b50156104d95760207fce2308ee613bae165226bc87fea41850f1fd4e8c07f19e7015e46017c9cb3a8c91835f525f825260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff8316179055604051908152a2005b7f5a4f9775000000000000000000000000000000000000000000000000000000005f5260045ffd5b6040517fbf7e214f0000000000000000000000000000000000000000000000000000000081529150602082600481875afa918215610248575f926105f0575b507fffffffff00000000000000000000000000000000000000000000000000000000606460209273ffffffffffffffffffffffffffffffffffffffff60405195869485937fb7009613000000000000000000000000000000000000000000000000000000008552336004860152306024860152166044840152165afa908115610248575f916105d1575b5083610471565b6105ea915060203d6020116102415761023381836106e7565b836105ca565b9091506020813d602011610659575b8161060c602093836106e7565b810103126100b9575173ffffffffffffffffffffffffffffffffffffffff811681036100b957907fffffffff00000000000000000000000000000000000000000000000000000000610540565b3d91506105ff565b506020813d6020116106bc575b8161067b602093836106e7565b810103126100b9575173ffffffffffffffffffffffffffffffffffffffff811681036100b95773ffffffffffffffffffffffffffffffffffffffff9061044f565b3d915061066e565b6004359073ffffffffffffffffffffffffffffffffffffffff821682036100b957565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761072857604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b908160209103126100b9575180151581036100b95790565b156107755750565b73ffffffffffffffffffffffffffffffffffffffff907f0562fa43000000000000000000000000000000000000000000000000000000005f521660045260245ffdfea164736f6c634300081d000a0000000000000000000000003a91a31cb3dc49b4db9ce721f50a9d076c8d739b
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f35908160e01c91826370598155146103b957505080638359b8d214610352578063abd626b0146100bd5763bb923cec1461004b575f80fd5b346100b9575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b957602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003a91a31cb3dc49b4db9ce721f50a9d076c8d739b168152f35b5f80fd5b346100b95760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b9576100f46106c4565b60243573ffffffffffffffffffffffffffffffffffffffff8116918282036100b9576044359073ffffffffffffffffffffffffffffffffffffffff82168092036100b95773ffffffffffffffffffffffffffffffffffffffff811691808314159081610347575b508061033e575b80610335575b6102f6575b81158015610253575b610180925061076d565b81158015610195575b610193925061076d565b005b50604051917fdf592f7d000000000000000000000000000000000000000000000000000000008352600483015260208260248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003a91a31cb3dc49b4db9ce721f50a9d076c8d739b165afa801561024857610193925f91610219575b5015610189565b61023b915060203d602011610241575b61023381836106e7565b810190610755565b83610212565b503d610229565b6040513d5f823e3d90fd5b50604051917fdf592f7d000000000000000000000000000000000000000000000000000000008352600483015260208260248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003a91a31cb3dc49b4db9ce721f50a9d076c8d739b165afa801561024857610180925f916102d7575b5015610176565b6102f0915060203d6020116102415761023381836106e7565b856102d0565b335f525f60205260ff60405f20541661016d577f817720f8000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b50831515610168565b50811515610162565b90508414158561015b565b346100b95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b95773ffffffffffffffffffffffffffffffffffffffff61039e6106c4565b165f525f602052602060ff60405f2054166040519015158152f35b346100b95760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100b9576103f06106c4565b90602435918215158093036100b95773ffffffffffffffffffffffffffffffffffffffff16927f8da5cb5b000000000000000000000000000000000000000000000000000000008152602081600481875afa8015610248575f90610661575b73ffffffffffffffffffffffffffffffffffffffff9150163314908115610501575b50156104d95760207fce2308ee613bae165226bc87fea41850f1fd4e8c07f19e7015e46017c9cb3a8c91835f525f825260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff8316179055604051908152a2005b7f5a4f9775000000000000000000000000000000000000000000000000000000005f5260045ffd5b6040517fbf7e214f0000000000000000000000000000000000000000000000000000000081529150602082600481875afa918215610248575f926105f0575b507fffffffff00000000000000000000000000000000000000000000000000000000606460209273ffffffffffffffffffffffffffffffffffffffff60405195869485937fb7009613000000000000000000000000000000000000000000000000000000008552336004860152306024860152166044840152165afa908115610248575f916105d1575b5083610471565b6105ea915060203d6020116102415761023381836106e7565b836105ca565b9091506020813d602011610659575b8161060c602093836106e7565b810103126100b9575173ffffffffffffffffffffffffffffffffffffffff811681036100b957907fffffffff00000000000000000000000000000000000000000000000000000000610540565b3d91506105ff565b506020813d6020116106bc575b8161067b602093836106e7565b810103126100b9575173ffffffffffffffffffffffffffffffffffffffff811681036100b95773ffffffffffffffffffffffffffffffffffffffff9061044f565b3d915061066e565b6004359073ffffffffffffffffffffffffffffffffffffffff821682036100b957565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761072857604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b908160209103126100b9575180151581036100b95790565b156107755750565b73ffffffffffffffffffffffffffffffffffffffff907f0562fa43000000000000000000000000000000000000000000000000000000005f521660045260245ffdfea164736f6c634300081d000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003a91a31cb3dc49b4db9ce721f50a9d076c8d739b
-----Decoded View---------------
Arg [0] : oracle_ (address): 0x3A91A31cB3dC49b4db9Ce721F50a9D076c8D739B
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000003a91a31cb3dc49b4db9ce721f50a9d076c8d739b
Loading...
Loading
Loading...
Loading
Loading...
Loading
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 ]
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.