Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Latest 25 from a total of 166 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Manage Vault Wit... | 23729444 | 25 hrs ago | IN | 0 ETH | 0.0002218 | ||||
| Manage Vault Wit... | 23727456 | 31 hrs ago | IN | 0 ETH | 0.00446231 | ||||
| Manage Vault Wit... | 23727451 | 31 hrs ago | IN | 0 ETH | 0.00416675 | ||||
| Set Manage Root | 23727352 | 32 hrs ago | IN | 0 ETH | 0.00025057 | ||||
| Set Manage Root | 23727352 | 32 hrs ago | IN | 0 ETH | 0.00025057 | ||||
| Set Manage Root | 23727350 | 32 hrs ago | IN | 0 ETH | 0.0002516 | ||||
| Set Manage Root | 23727349 | 32 hrs ago | IN | 0 ETH | 0.0002601 | ||||
| Manage Vault Wit... | 23727251 | 32 hrs ago | IN | 0 ETH | 0.0015888 | ||||
| Manage Vault Wit... | 23722618 | 47 hrs ago | IN | 0 ETH | 0.00043677 | ||||
| Manage Vault Wit... | 23722610 | 2 days ago | IN | 0 ETH | 0.00050046 | ||||
| Manage Vault Wit... | 23722598 | 2 days ago | IN | 0 ETH | 0.00052535 | ||||
| Manage Vault Wit... | 23722558 | 2 days ago | IN | 0 ETH | 0.00053791 | ||||
| Manage Vault Wit... | 23722554 | 2 days ago | IN | 0 ETH | 0.00046201 | ||||
| Manage Vault Wit... | 23722545 | 2 days ago | IN | 0 ETH | 0.00049245 | ||||
| Manage Vault Wit... | 23722537 | 2 days ago | IN | 0 ETH | 0.00046414 | ||||
| Manage Vault Wit... | 23722529 | 2 days ago | IN | 0 ETH | 0.00004671 | ||||
| Manage Vault Wit... | 23722493 | 2 days ago | IN | 0 ETH | 0.00006512 | ||||
| Manage Vault Wit... | 23722448 | 2 days ago | IN | 0 ETH | 0.00125785 | ||||
| Set Manage Root | 23722200 | 2 days ago | IN | 0 ETH | 0.00000933 | ||||
| Set Manage Root | 23722199 | 2 days ago | IN | 0 ETH | 0.00000922 | ||||
| Set Manage Root | 23722199 | 2 days ago | IN | 0 ETH | 0.00000922 | ||||
| Set Manage Root | 23722191 | 2 days ago | IN | 0 ETH | 0.00000856 | ||||
| Manage Vault Wit... | 23714729 | 3 days ago | IN | 0 ETH | 0.00000853 | ||||
| Manage Vault Wit... | 23714728 | 3 days ago | IN | 0 ETH | 0.00007502 | ||||
| Manage Vault Wit... | 23714721 | 3 days ago | IN | 0 ETH | 0.00000809 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60c06040 | 22555405 | 165 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ManagerWithMerkleVerification
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;
import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol";
import {BoringVault} from "src/base/BoringVault.sol";
import {MerkleProofLib} from "@solmate/utils/MerkleProofLib.sol";
import {ERC20} from "@solmate/tokens/ERC20.sol";
import {SafeTransferLib} from "@solmate/utils/SafeTransferLib.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {BalancerVault} from "src/interfaces/BalancerVault.sol";
import {Auth, Authority} from "@solmate/auth/Auth.sol";
import {IPausable} from "src/interfaces/IPausable.sol";
import {DroneLib} from "src/base/Drones/DroneLib.sol";
contract ManagerWithMerkleVerification is Auth, IPausable {
using FixedPointMathLib for uint256;
using SafeTransferLib for ERC20;
using Address for address;
// ========================================= STATE =========================================
/**
* @notice A merkle tree root that restricts what data can be passed to the BoringVault.
* @dev Maps a strategist address to their specific merkle root.
* @dev Each leaf is composed of the keccak256 hash of abi.encodePacked {decodersAndSanitizer, target, valueIsNonZero, selector, argumentAddress_0, ...., argumentAddress_N}
* Where:
* - decodersAndSanitizer is the addres to call to extract packed address arguments from the calldata
* - target is the address to make the call to
* - valueIsNonZero is a bool indicating whether or not the value is non-zero
* - selector is the function selector on target
* - argumentAddress is each allowed address argument in that call
*/
mapping(address => bytes32) public manageRoot;
/**
* @notice Bool indicating whether or not this contract is actively performing a flash loan.
* @dev Used to block flash loans that are initiated outside a manage call.
*/
bool internal performingFlashLoan;
/**
* @notice keccak256 hash of flash loan data.
*/
bytes32 internal flashLoanIntentHash = bytes32(0);
/**
* @notice Used to pause calls to `manageVaultWithMerkleVerification`.
*/
bool public isPaused;
//============================== ERRORS ===============================
error ManagerWithMerkleVerification__InvalidManageProofLength();
error ManagerWithMerkleVerification__InvalidTargetDataLength();
error ManagerWithMerkleVerification__InvalidValuesLength();
error ManagerWithMerkleVerification__InvalidDecodersAndSanitizersLength();
error ManagerWithMerkleVerification__FlashLoanNotExecuted();
error ManagerWithMerkleVerification__FlashLoanNotInProgress();
error ManagerWithMerkleVerification__BadFlashLoanIntentHash();
error ManagerWithMerkleVerification__FailedToVerifyManageProof(address target, bytes targetData, uint256 value);
error ManagerWithMerkleVerification__Paused();
error ManagerWithMerkleVerification__OnlyCallableByBoringVault();
error ManagerWithMerkleVerification__OnlyCallableByBalancerVault();
error ManagerWithMerkleVerification__TotalSupplyMustRemainConstantDuringPlatform();
//============================== EVENTS ===============================
event ManageRootUpdated(address indexed strategist, bytes32 oldRoot, bytes32 newRoot);
event BoringVaultManaged(uint256 callsMade);
event Paused();
event Unpaused();
//============================== IMMUTABLES ===============================
/**
* @notice The BoringVault this contract can manage.
*/
BoringVault public immutable vault;
/**
* @notice The balancer vault this contract can use for flash loans.
*/
BalancerVault public immutable balancerVault;
constructor(address _owner, address _vault, address _balancerVault) Auth(_owner, Authority(address(0))) {
vault = BoringVault(payable(_vault));
balancerVault = BalancerVault(_balancerVault);
}
// ========================================= ADMIN FUNCTIONS =========================================
/**
* @notice Sets the manageRoot.
* @dev Callable by OWNER_ROLE.
*/
function setManageRoot(address strategist, bytes32 _manageRoot) external requiresAuth {
bytes32 oldRoot = manageRoot[strategist];
manageRoot[strategist] = _manageRoot;
emit ManageRootUpdated(strategist, oldRoot, _manageRoot);
}
/**
* @notice Pause this contract, which prevents future calls to `manageVaultWithMerkleVerification`.
* @dev Callable by MULTISIG_ROLE.
*/
function pause() external requiresAuth {
isPaused = true;
emit Paused();
}
/**
* @notice Unpause this contract, which allows future calls to `manageVaultWithMerkleVerification`.
* @dev Callable by MULTISIG_ROLE.
*/
function unpause() external requiresAuth {
isPaused = false;
emit Unpaused();
}
// ========================================= STRATEGIST FUNCTIONS =========================================
/**
* @notice Allows strategist to manage the BoringVault.
* @dev The strategist must provide a merkle proof for every call that verifiees they are allowed to make that call.
* @dev Callable by MANAGER_INTERNAL_ROLE.
* @dev Callable by STRATEGIST_ROLE.
* @dev Callable by MICRO_MANAGER_ROLE.
*/
function manageVaultWithMerkleVerification(
bytes32[][] calldata manageProofs,
address[] calldata decodersAndSanitizers,
address[] calldata targets,
bytes[] calldata targetData,
uint256[] calldata values
) external requiresAuth {
if (isPaused) revert ManagerWithMerkleVerification__Paused();
uint256 targetsLength = targets.length;
if (targetsLength != manageProofs.length) revert ManagerWithMerkleVerification__InvalidManageProofLength();
if (targetsLength != targetData.length) revert ManagerWithMerkleVerification__InvalidTargetDataLength();
if (targetsLength != values.length) revert ManagerWithMerkleVerification__InvalidValuesLength();
if (targetsLength != decodersAndSanitizers.length) {
revert ManagerWithMerkleVerification__InvalidDecodersAndSanitizersLength();
}
bytes32 strategistManageRoot = manageRoot[msg.sender];
uint256 totalSupply = vault.totalSupply();
for (uint256 i; i < targetsLength; ++i) {
_verifyCallData(
strategistManageRoot, manageProofs[i], decodersAndSanitizers[i], targets[i], values[i], targetData[i]
);
vault.manage(targets[i], targetData[i], values[i]);
}
if (totalSupply != vault.totalSupply()) {
revert ManagerWithMerkleVerification__TotalSupplyMustRemainConstantDuringPlatform();
}
emit BoringVaultManaged(targetsLength);
}
// ========================================= FLASH LOAN FUNCTIONS =========================================
/**
* @notice In order to perform a flash loan,
* 1) Merkle root must contain the leaf(address(this), this.flashLoan.selector, ARGUMENT_ADDRESSES ...)
* 2) Strategist must initiate the flash loan using `manageVaultWithMerkleVerification`
* 3) balancerVault MUST callback to this contract with the same userData
*/
function flashLoan(
address recipient,
address[] calldata tokens,
uint256[] calldata amounts,
bytes calldata userData
) external {
if (msg.sender != address(vault)) revert ManagerWithMerkleVerification__OnlyCallableByBoringVault();
flashLoanIntentHash = keccak256(userData);
performingFlashLoan = true;
balancerVault.flashLoan(recipient, tokens, amounts, userData);
performingFlashLoan = false;
if (flashLoanIntentHash != bytes32(0)) revert ManagerWithMerkleVerification__FlashLoanNotExecuted();
}
/**
* @notice Add support for balancer flash loans.
* @dev userData can optionally have salt encoded at the end of it, in order to change the intentHash,
* if a flash loan is exact userData is being repeated, and their is fear of 3rd parties
* front-running the rebalance.
*/
function receiveFlashLoan(
address[] calldata tokens,
uint256[] calldata amounts,
uint256[] calldata feeAmounts,
bytes calldata userData
) external {
if (msg.sender != address(balancerVault)) revert ManagerWithMerkleVerification__OnlyCallableByBalancerVault();
if (!performingFlashLoan) revert ManagerWithMerkleVerification__FlashLoanNotInProgress();
// Validate userData using intentHash.
bytes32 intentHash = keccak256(userData);
if (intentHash != flashLoanIntentHash) revert ManagerWithMerkleVerification__BadFlashLoanIntentHash();
// reset intent hash to prevent replays.
flashLoanIntentHash = bytes32(0);
// Transfer tokens to vault.
for (uint256 i = 0; i < amounts.length; ++i) {
ERC20(tokens[i]).safeTransfer(address(vault), amounts[i]);
}
{
(
bytes32[][] memory manageProofs,
address[] memory decodersAndSanitizers,
address[] memory targets,
bytes[] memory data,
uint256[] memory values
) = abi.decode(userData, (bytes32[][], address[], address[], bytes[], uint256[]));
ManagerWithMerkleVerification(address(this)).manageVaultWithMerkleVerification(
manageProofs, decodersAndSanitizers, targets, data, values
);
}
// Transfer tokens back to balancer.
// Have vault transfer amount + fees back to balancer
bytes[] memory transferData = new bytes[](amounts.length);
for (uint256 i; i < amounts.length; ++i) {
transferData[i] =
abi.encodeWithSelector(ERC20.transfer.selector, address(balancerVault), (amounts[i] + feeAmounts[i]));
}
// Values is always zero, just pass in an array of zeroes.
vault.manage(tokens, transferData, new uint256[](amounts.length));
}
// ========================================= INTERNAL HELPER FUNCTIONS =========================================
/**
* @notice Helper function to decode, sanitize, and verify call data.
*/
function _verifyCallData(
bytes32 currentManageRoot,
bytes32[] calldata manageProof,
address decoderAndSanitizer,
address target,
uint256 value,
bytes calldata targetData
) internal view {
// Use address decoder to get addresses in call data.
bytes memory packedArgumentAddresses = abi.decode(decoderAndSanitizer.functionStaticCall(targetData), (bytes));
address droneTarget = DroneLib.extractTargetFromInput(targetData);
if (droneTarget != address(0)) {
packedArgumentAddresses = abi.encodePacked(packedArgumentAddresses, droneTarget);
}
if (
!_verifyManageProof(
currentManageRoot,
manageProof,
target,
decoderAndSanitizer,
value,
bytes4(targetData),
packedArgumentAddresses
)
) {
revert ManagerWithMerkleVerification__FailedToVerifyManageProof(target, targetData, value);
}
}
/**
* @notice Helper function to verify a manageProof is valid.
*/
function _verifyManageProof(
bytes32 root,
bytes32[] calldata proof,
address target,
address decoderAndSanitizer,
uint256 value,
bytes4 selector,
bytes memory packedArgumentAddresses
) internal pure returns (bool) {
bool valueNonZero = value > 0;
bytes32 leaf =
keccak256(abi.encodePacked(decoderAndSanitizer, target, valueNonZero, selector, packedArgumentAddresses));
return MerkleProofLib.verify(proof, root, leaf);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
/*//////////////////////////////////////////////////////////////
SIMPLIFIED FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
uint256 internal constant MAX_UINT256 = 2**256 - 1;
uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.
function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
}
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
}
function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
}
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
}
/*//////////////////////////////////////////////////////////////
LOW LEVEL FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function mulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
revert(0, 0)
}
// Divide x * y by the denominator.
z := div(mul(x, y), denominator)
}
}
function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
revert(0, 0)
}
// If x * y modulo the denominator is strictly greater than 0,
// 1 is added to round up the division of x * y by the denominator.
z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
}
}
function rpow(
uint256 x,
uint256 n,
uint256 scalar
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := scalar
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store scalar in z for now.
z := scalar
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, scalar)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, scalar)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, scalar)
}
}
}
}
}
/*//////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
let y := x // We start y at x, which will help us make our initial estimate.
z := 181 // The "correct" value is 1, but this saves a multiplication later.
// This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
// start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.
// We check y >= 2^(k + 8) but shift right by k bits
// each branch to ensure that if x >= 256, then y >= 256.
if iszero(lt(y, 0x10000000000000000000000000000000000)) {
y := shr(128, y)
z := shl(64, z)
}
if iszero(lt(y, 0x1000000000000000000)) {
y := shr(64, y)
z := shl(32, z)
}
if iszero(lt(y, 0x10000000000)) {
y := shr(32, y)
z := shl(16, z)
}
if iszero(lt(y, 0x1000000)) {
y := shr(16, y)
z := shl(8, z)
}
// Goal was to get z*z*y within a small factor of x. More iterations could
// get y in a tighter range. Currently, we will have y in [256, 256*2^16).
// We ensured y >= 256 so that the relative difference between y and y+1 is small.
// That's not possible if x < 256 but we can just verify those cases exhaustively.
// Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
// Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
// Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.
// For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
// (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.
// Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
// sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.
// There is no overflow risk here since y < 2^136 after the first branch above.
z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.
// Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// If x+1 is a perfect square, the Babylonian method cycles between
// floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
// See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
// Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
// If you don't care whether the floor or ceil square root is returned, you can remove this statement.
z := sub(z, lt(div(x, z), z))
}
}
function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Mod x by y. Note this will return
// 0 instead of reverting if y is zero.
z := mod(x, y)
}
}
function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
// Divide x by y. Note this will return
// 0 instead of reverting if y is zero.
r := div(x, y)
}
}
function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Add 1 to x * y if x % y > 0. Note this will
// return 0 instead of reverting if y is zero.
z := add(gt(mod(x, y), 0), div(x, y))
}
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol";
import {SafeTransferLib} from "@solmate/utils/SafeTransferLib.sol";
import {ERC20} from "@solmate/tokens/ERC20.sol";
import {BeforeTransferHook} from "src/interfaces/BeforeTransferHook.sol";
import {Auth, Authority} from "@solmate/auth/Auth.sol";
contract BoringVault is ERC20, Auth, ERC721Holder, ERC1155Holder {
using Address for address;
using SafeTransferLib for ERC20;
using FixedPointMathLib for uint256;
// ========================================= STATE =========================================
/**
* @notice Contract responsbile for implementing `beforeTransfer`.
*/
BeforeTransferHook public hook;
//============================== EVENTS ===============================
event Enter(address indexed from, address indexed asset, uint256 amount, address indexed to, uint256 shares);
event Exit(address indexed to, address indexed asset, uint256 amount, address indexed from, uint256 shares);
//============================== CONSTRUCTOR ===============================
constructor(address _owner, string memory _name, string memory _symbol, uint8 _decimals)
ERC20(_name, _symbol, _decimals)
Auth(_owner, Authority(address(0)))
{}
//============================== MANAGE ===============================
/**
* @notice Allows manager to make an arbitrary function call from this contract.
* @dev Callable by MANAGER_ROLE.
*/
function manage(address target, bytes calldata data, uint256 value)
external
requiresAuth
returns (bytes memory result)
{
result = target.functionCallWithValue(data, value);
}
/**
* @notice Allows manager to make arbitrary function calls from this contract.
* @dev Callable by MANAGER_ROLE.
*/
function manage(address[] calldata targets, bytes[] calldata data, uint256[] calldata values)
external
requiresAuth
returns (bytes[] memory results)
{
uint256 targetsLength = targets.length;
results = new bytes[](targetsLength);
for (uint256 i; i < targetsLength; ++i) {
results[i] = targets[i].functionCallWithValue(data[i], values[i]);
}
}
//============================== ENTER ===============================
/**
* @notice Allows minter to mint shares, in exchange for assets.
* @dev If assetAmount is zero, no assets are transferred in.
* @dev Callable by MINTER_ROLE.
*/
function enter(address from, ERC20 asset, uint256 assetAmount, address to, uint256 shareAmount)
external
requiresAuth
{
// Transfer assets in
if (assetAmount > 0) asset.safeTransferFrom(from, address(this), assetAmount);
// Mint shares.
_mint(to, shareAmount);
emit Enter(from, address(asset), assetAmount, to, shareAmount);
}
//============================== EXIT ===============================
/**
* @notice Allows burner to burn shares, in exchange for assets.
* @dev If assetAmount is zero, no assets are transferred out.
* @dev Callable by BURNER_ROLE.
*/
function exit(address to, ERC20 asset, uint256 assetAmount, address from, uint256 shareAmount)
external
requiresAuth
{
// Burn shares.
_burn(from, shareAmount);
// Transfer assets out.
if (assetAmount > 0) asset.safeTransfer(to, assetAmount);
emit Exit(to, address(asset), assetAmount, from, shareAmount);
}
//============================== BEFORE TRANSFER HOOK ===============================
/**
* @notice Sets the share locker.
* @notice If set to zero address, the share locker logic is disabled.
* @dev Callable by OWNER_ROLE.
*/
function setBeforeTransferHook(address _hook) external requiresAuth {
hook = BeforeTransferHook(_hook);
}
/**
* @notice Call `beforeTransferHook` passing in `from` `to`, and `msg.sender`.
*/
function _callBeforeTransfer(address from, address to) internal view {
if (address(hook) != address(0)) hook.beforeTransfer(from, to, msg.sender);
}
function transfer(address to, uint256 amount) public override returns (bool) {
_callBeforeTransfer(msg.sender, to);
return super.transfer(to, amount);
}
function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
_callBeforeTransfer(from, to);
return super.transferFrom(from, to, amount);
}
//============================== RECEIVE ===============================
receive() external payable {}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/// @notice Gas optimized merkle proof verification library.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
library MerkleProofLib {
function verify(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool isValid) {
/// @solidity memory-safe-assembly
assembly {
if proof.length {
// Left shifting by 5 is like multiplying by 32.
let end := add(proof.offset, shl(5, proof.length))
// Initialize offset to the offset of the proof in calldata.
let offset := proof.offset
// Iterate over proof elements to compute root hash.
// prettier-ignore
for {} 1 {} {
// Slot where the leaf should be put in scratch space. If
// leaf > calldataload(offset): slot 32, otherwise: slot 0.
let leafSlot := shl(5, gt(leaf, calldataload(offset)))
// Store elements to hash contiguously in scratch space.
// The xor puts calldataload(offset) in whichever slot leaf
// is not occupying, so 0 if leafSlot is 32, and 32 otherwise.
mstore(leafSlot, leaf)
mstore(xor(leafSlot, 32), calldataload(offset))
// Reuse leaf to store the hash to reduce stack operations.
leaf := keccak256(0, 64) // Hash both slots of scratch space.
offset := add(offset, 32) // Shift 1 word per cycle.
// prettier-ignore
if iszero(lt(offset, end)) { break }
}
}
isValid := eq(leaf, root) // The proof is valid if the roots match.
}
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;
import {DecoderCustomTypes} from "src/interfaces/DecoderCustomTypes.sol";
interface BalancerVault {
function flashLoan(address, address[] memory tokens, uint256[] memory amounts, bytes calldata userData) external;
function swap(
DecoderCustomTypes.SingleSwap memory singleSwap,
DecoderCustomTypes.FundManagement memory funds,
uint256 limit,
uint256 deadline
) external returns (uint256 amountCalculated);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @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);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;
interface IPausable {
function pause() external;
function unpause() external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;
library DroneLib {
bytes32 internal constant TARGET_FLAG = keccak256(bytes("DroneLib.target"));
function extractTargetFromCalldata() internal pure returns (address target) {
target = extractTargetFromInput(msg.data);
}
function extractTargetFromInput(bytes calldata data) internal pure returns (address target) {
// Look at the last 32 bytes of calldata and see if the TARGET_FLAG is there.
uint256 length = data.length;
if (length >= 68) {
bytes32 flag = bytes32(data[length - 32:]);
if (flag == TARGET_FLAG) {
// If the flag is there, extract the target from the calldata.
target = address(bytes20(data[length - 52:length - 32]));
}
}
// else no target present, so target is address(0).
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol)
pragma solidity ^0.8.20;
import {IERC721Receiver} from "../IERC721Receiver.sol";
/**
* @dev Implementation of the {IERC721Receiver} interface.
*
* Accepts all token transfers.
* Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or
* {IERC721-setApprovalForAll}.
*/
abstract contract ERC721Holder is IERC721Receiver {
/**
* @dev See {IERC721Receiver-onERC721Received}.
*
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) {
return this.onERC721Received.selector;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/utils/ERC1155Holder.sol)
pragma solidity ^0.8.20;
import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol";
import {IERC1155Receiver} from "../IERC1155Receiver.sol";
/**
* @dev Simple implementation of `IERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
*
* IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
* stuck.
*/
abstract contract ERC1155Holder is ERC165, IERC1155Receiver {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;
interface BeforeTransferHook {
function beforeTransfer(address from, address to, address operator) external view;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;
contract DecoderCustomTypes {
// ========================================= BALANCER =========================================
struct JoinPoolRequest {
address[] assets;
uint256[] maxAmountsIn;
bytes userData;
bool fromInternalBalance;
}
struct ExitPoolRequest {
address[] assets;
uint256[] minAmountsOut;
bytes userData;
bool toInternalBalance;
}
enum SwapKind {
GIVEN_IN,
GIVEN_OUT
}
struct SingleSwap {
bytes32 poolId;
SwapKind kind;
address assetIn;
address assetOut;
uint256 amount;
bytes userData;
}
struct FundManagement {
address sender;
bool fromInternalBalance;
address recipient;
bool toInternalBalance;
}
// ========================================= UNISWAP V3 =========================================
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
struct IncreaseLiquidityParams {
uint256 tokenId;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
struct DecreaseLiquidityParams {
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
struct CollectParams {
uint256 tokenId;
address recipient;
uint128 amount0Max;
uint128 amount1Max;
}
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
struct ExactInputParamsRouter02 {
bytes path;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
}
struct PancakeSwapExactInputParams {
bytes path;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
}
// ========================================= UNISWAP V4 =========================================
struct SwapParams {
/// Whether to swap token0 for token1 or vice versa
bool zeroForOne;
/// The desired input amount if negative (exactIn), or the desired output amount if positive (exactOut)
int256 amountSpecified;
/// The sqrt price at which, if reached, the swap will stop executing
uint160 sqrtPriceLimitX96;
}
struct PoolKey {
/// @notice The lower currency of the pool, sorted numerically
address currency0;
/// @notice The higher currency of the pool, sorted numerically
address currency1;
/// @notice The pool LP fee, capped at 1_000_000. If the highest bit is 1, the pool has a dynamic fee and must be exactly equal to 0x800000
uint24 fee;
/// @notice Ticks that involve positions must be a multiple of tick spacing
int24 tickSpacing;
/// @notice The hooks of the pool
address hooks;
}
/// @dev comes from IV4 Router
struct ExactInputSingleParams {
PoolKey poolKey;
bool zeroForOne;
uint128 amountIn;
uint128 amountOutMinimum;
bytes hookData;
}
/// @notice Parameters for a single-hop exact-output swap
struct ExactOutputSingleParams {
PoolKey poolKey;
bool zeroForOne;
uint128 amountOut;
uint128 amountInMaximum;
bytes hookData;
}
// ========================================= MORPHO BLUE =========================================
struct MarketParams {
address loanToken;
address collateralToken;
address oracle;
address irm;
uint256 lltv;
}
// ========================================= 1INCH =========================================
struct SwapDescription {
address srcToken;
address dstToken;
address payable srcReceiver;
address payable dstReceiver;
uint256 amount;
uint256 minReturnAmount;
uint256 flags;
}
// ========================================= PENDLE =========================================
struct TokenInput {
// TOKEN DATA
address tokenIn;
uint256 netTokenIn;
address tokenMintSy;
// AGGREGATOR DATA
address pendleSwap;
SwapData swapData;
}
struct TokenOutput {
// TOKEN DATA
address tokenOut;
uint256 minTokenOut;
address tokenRedeemSy;
// AGGREGATOR DATA
address pendleSwap;
SwapData swapData;
}
struct ApproxParams {
uint256 guessMin;
uint256 guessMax;
uint256 guessOffchain; // pass 0 in to skip this variable
uint256 maxIteration; // every iteration, the diff between guessMin and guessMax will be divided by 2
uint256 eps; // the max eps between the returned result & the correct result, base 1e18. Normally this number will be set
// to 1e15 (1e18/1000 = 0.1%)
}
struct SwapData {
SwapType swapType;
address extRouter;
bytes extCalldata;
bool needScale;
}
enum SwapType {
NONE,
KYBERSWAP,
ONE_INCH,
// ETH_WETH not used in Aggregator
ETH_WETH
}
struct LimitOrderData {
address limitRouter;
uint256 epsSkipMarket; // only used for swap operations, will be ignored otherwise
FillOrderParams[] normalFills;
FillOrderParams[] flashFills;
bytes optData;
}
struct FillOrderParams {
Order order;
bytes signature;
uint256 makingAmount;
}
struct Order {
uint256 salt;
uint256 expiry;
uint256 nonce;
OrderType orderType;
address token;
address YT;
address maker;
address receiver;
uint256 makingAmount;
uint256 lnImpliedRate;
uint256 failSafeRate;
bytes permit;
}
enum OrderType {
SY_FOR_PT,
PT_FOR_SY,
SY_FOR_YT,
YT_FOR_SY
}
// ========================================= EIGEN LAYER =========================================
struct QueuedWithdrawalParams {
// Array of strategies that the QueuedWithdrawal contains
address[] strategies;
// Array containing the amount of shares in each Strategy in the `strategies` array
uint256[] shares;
// The address of the withdrawer
address withdrawer;
}
struct Withdrawal {
// The address that originated the Withdrawal
address staker;
// The address that the staker was delegated to at the time that the Withdrawal was created
address delegatedTo;
// The address that can complete the Withdrawal + will receive funds when completing the withdrawal
address withdrawer;
// Nonce used to guarantee that otherwise identical withdrawals have unique hashes
uint256 nonce;
// Block number when the Withdrawal was created
uint32 startBlock;
// Array of strategies that the Withdrawal contains
address[] strategies;
// Array containing the amount of shares in each Strategy in the `strategies` array
uint256[] shares;
}
struct SignatureWithExpiry {
// the signature itself, formatted as a single bytes object
bytes signature;
// the expiration timestamp (UTC) of the signature
uint256 expiry;
}
struct EarnerTreeMerkleLeaf {
address earner;
bytes32 earnerTokenRoot;
}
struct TokenTreeMerkleLeaf {
address token;
uint256 cumulativeEarnings;
}
struct RewardsMerkleClaim {
uint32 rootIndex;
uint32 earnerIndex;
bytes earnerTreeProof;
EarnerTreeMerkleLeaf earnerLeaf;
uint32[] tokenIndices;
bytes[] tokenTreeProofs;
TokenTreeMerkleLeaf[] tokenLeaves;
}
// ========================================= CCIP =========================================
// If extraArgs is empty bytes, the default is 200k gas limit.
struct EVM2AnyMessage {
bytes receiver; // abi.encode(receiver address) for dest EVM chains
bytes data; // Data payload
EVMTokenAmount[] tokenAmounts; // Token transfers
address feeToken; // Address of feeToken. address(0) means you will send msg.value.
bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV2)
}
/// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
struct EVMTokenAmount {
address token; // token address on the local chain.
uint256 amount; // Amount of tokens.
}
struct EVMExtraArgsV1 {
uint256 gasLimit;
}
// ========================================= OFT =========================================
struct SendParam {
uint32 dstEid; // Destination endpoint ID.
bytes32 to; // Recipient address.
uint256 amountLD; // Amount to send in local decimals.
uint256 minAmountLD; // Minimum amount to send in local decimals.
bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message.
bytes composeMsg; // The composed message for the send() operation.
bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations.
}
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}
// ========================================= L1StandardBridge =========================================
struct WithdrawalTransaction {
uint256 nonce;
address sender;
address target;
uint256 value;
uint256 gasLimit;
bytes data;
}
struct OutputRootProof {
bytes32 version;
bytes32 stateRoot;
bytes32 messagePasserStorageRoot;
bytes32 latestBlockhash;
}
// ========================================= Mantle L1StandardBridge =========================================
struct MantleWithdrawalTransaction {
uint256 nonce;
address sender;
address target;
uint256 mntValue;
uint256 value;
uint256 gasLimit;
bytes data;
}
// ========================================= Linea Bridge =========================================
struct ClaimMessageWithProofParams {
bytes32[] proof;
uint256 messageNumber;
uint32 leafIndex;
address from;
address to;
uint256 fee;
uint256 value;
address payable feeRecipient;
bytes32 merkleRoot;
bytes data;
}
// ========================================= Scroll Bridge =========================================
struct L2MessageProof {
uint256 batchIndex;
bytes merkleProof;
}
// ========================================= Camelot V3 =========================================
struct CamelotMintParams {
address token0;
address token1;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
// ========================================= Velodrome V3 =========================================
struct VelodromeMintParams {
address token0;
address token1;
int24 tickSpacing;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
uint160 sqrtPriceX96;
}
// ========================================= Karak =========================================
struct QueuedWithdrawal {
address staker;
address delegatedTo;
uint256 nonce;
uint256 start;
WithdrawRequest request;
}
struct WithdrawRequest {
address[] vaults;
uint256[] shares;
address withdrawer;
}
// ========================================= Term Finance ==================================
/// @dev TermAuctionOfferSubmission represents an offer submission to offeror an amount of money for a specific interest rate
struct TermAuctionOfferSubmission {
/// @dev For an existing offer this is the unique onchain identifier for this offer. For a new offer this is a randomized input that will be used to generate the unique onchain identifier.
bytes32 id;
/// @dev The address of the offeror
address offeror;
/// @dev Hash of the offered price as a percentage of the initial loaned amount vs amount returned at maturity. This stores 9 decimal places
bytes32 offerPriceHash;
/// @dev The maximum amount of purchase tokens that can be lent
uint256 amount;
/// @dev The address of the ERC20 purchase token
address purchaseToken;
}
// ========================================= Dolomite Finance ==================================
enum BalanceCheckFlag {
Both,
From,
To,
None
}
// ========================================= Silo Finance ==================================
/// @dev There are 2 types of accounting in the system: for non-borrowable collateral deposit called "protected" and
/// for borrowable collateral deposit called "collateral". System does
/// identical calculations for each type of accounting but it uses different data. To avoid code duplication
/// this enum is used to decide which data should be read.
enum CollateralType {
Protected, // default
Collateral
}
enum ActionType {
Deposit,
Mint,
Repay,
RepayShares
}
struct Action {
// what do you want to do?
uint8 actionType;
// which Silo are you interacting with?
address silo;
// what asset do you want to use?
address asset;
// options specific for actions
bytes options;
}
struct AnyAction {
// how much assets or shares do you want to use?
uint256 amount;
// are you using Protected, Collateral
uint8 assetType;
}
// ========================================= LBTC Bridge ==================================
struct DepositBridgeAction {
uint256 fromChain;
bytes32 fromContract;
uint256 toChain;
address toContract;
address recipient;
uint64 amount;
uint256 nonce;
}
// ========================================= Odos ==================================
struct swapTokenInfo {
address inputToken;
uint256 inputAmount;
address inputReceiver;
address outputToken;
uint256 outputQuote;
uint256 outputMin;
address outputReceiver;
}
struct swapTokenInfoOogaBooga {
address inputToken;
uint256 inputAmount;
address outputToken;
uint256 outputQuote;
uint256 outputMin;
address outputReceiver;
}
// ========================================= Level ==================================
/// @dev for reference
//enum OrderType {
// MINT,
// REDEEM
//}
struct LevelOrder {
uint8 order_type;
address benefactor;
address beneficiary;
address collateral_asset;
uint256 collateral_amount;
uint256 lvlusd_amount;
}
struct Route {
address[] addresses;
uint256[] ratios;
}
// ========================================= Royco ==================================
struct APOffer { // RecipeMarketHub
uint256 offerID;
bytes32 targetMarketHash;
address ap;
address fundingVault;
uint256 quantity;
uint256 expiry;
address[] incentivesRequested;
uint256[] incentiveAmountsRequested;
}
struct APOfferVault { // VaultMarketHub (renamed to avoid collision)
uint256 offerID;
address targetVault;
address ap;
address fundingVault;
uint256 expiry;
address[] incentivesRequested;
uint256[] incentivesRatesRequested;
}
struct Reward {
uint48 startEpoch;
uint48 endEpoch;
address token;
uint256 rewardRate;
}
// ========================================= Permit2 ==================================
struct TokenSpenderPair {
address token;
address spender;
}
// ========================================= OnChainQueue ==================================
struct OnChainWithdraw {
uint96 nonce; // read from state, used to make it impossible for request Ids to be repeated.
address user; // msg.sender
address assetOut; // input sanitized
uint128 amountOfShares; // input transfered in
uint128 amountOfAssets; // derived from amountOfShares and price
uint40 creationTime; // time withdraw was made
uint24 secondsToMaturity; // in contract, from withdrawAsset?
uint24 secondsToDeadline; // in contract, from withdrawAsset? To get the deadline you take the creationTime add seconds to maturity, add the secondsToDeadline
}
// ========================================= Beraborrow ==================================
struct OpenDenVaultParams {
address denManager;
address collVault;
uint256 _maxFeePercentage;
uint256 _debtAmount;
uint256 _collAssetToDeposit;
address _upperHint;
address _lowerHint;
uint256 _minSharesMinted;
uint256 _collIndex;
bytes _preDeposit;
}
struct AdjustDenVaultParams {
address denManager;
address collVault;
uint256 _maxFeePercentage;
uint256 _collAssetToDeposit;
uint256 _collWithdrawal;
uint256 _debtChange;
bool _isDebtIncrease;
address _upperHint;
address _lowerHint;
bool unwrap;
uint256 _minSharesMinted;
uint256 _minAssetsWithdrawn;
uint256 _collIndex;
bytes _preDeposit;
}
struct RedeemCollateralVaultParams {
address denManager;
address collVault;
uint256 _debtAmount;
address _firstRedemptionHint;
address _upperPartialRedemptionHint;
address _lowerPartialRedemptionHint;
uint256 _partialRedemptionHintNICR;
uint256 _maxIterations;
uint256 _maxFeePercentage;
uint256 _minSharesWithdrawn;
uint256 minAssetsWithdrawn;
uint256 collIndex;
bool unwrap;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.20;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be
* reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Interface that must be implemented by smart contracts in order to receive
* ERC-1155 token transfers.
*/
interface IERC1155Receiver is IERC165 {
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @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 ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[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);
}{
"remappings": [
"@solmate/=lib/solmate/src/",
"@forge-std/=lib/forge-std/src/",
"@ds-test/=lib/forge-std/lib/ds-test/src/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"@ccip/=lib/ccip/",
"@oapp-auth/=lib/OAppAuth/src/",
"@devtools-oapp-evm/=lib/OAppAuth/lib/devtools/packages/oapp-evm/contracts/oapp/",
"@layerzerolabs/lz-evm-messagelib-v2/=lib/OAppAuth/node_modules/@layerzerolabs/lz-evm-messagelib-v2/",
"@layerzerolabs/lz-evm-protocol-v2/=lib/OAppAuth/lib/LayerZero-V2/packages/layerzero-v2/evm/protocol/",
"@layerzerolabs/oapp-evm/=lib/OAppAuth/lib/devtools/packages/oapp-evm/",
"@lz-oapp-evm/=lib/OAppAuth/lib/LayerZero-V2/packages/layerzero-v2/evm/oapp/contracts/oapp/",
"@sbu/=lib/OAppAuth/lib/solidity-bytes-utils/",
"LayerZero-V2/=lib/OAppAuth/lib/",
"LayerZero-v2/=lib/LayerZero-v2/",
"OAppAuth/=lib/OAppAuth/",
"ccip/=lib/ccip/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/OAppAuth/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"solidity-bytes-utils/=lib/OAppAuth/node_modules/solidity-bytes-utils/",
"solmate/=lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_balancerVault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__BadFlashLoanIntentHash","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"targetData","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"ManagerWithMerkleVerification__FailedToVerifyManageProof","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__FlashLoanNotExecuted","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__FlashLoanNotInProgress","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidDecodersAndSanitizersLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidManageProofLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidTargetDataLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidValuesLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__OnlyCallableByBalancerVault","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__OnlyCallableByBoringVault","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__Paused","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__TotalSupplyMustRemainConstantDuringPlatform","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"callsMade","type":"uint256"}],"name":"BoringVaultManaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategist","type":"address"},{"indexed":false,"internalType":"bytes32","name":"oldRoot","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"newRoot","type":"bytes32"}],"name":"ManageRootUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpaused","type":"event"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balancerVault","outputs":[{"internalType":"contract BalancerVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"flashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"manageRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[][]","name":"manageProofs","type":"bytes32[][]"},{"internalType":"address[]","name":"decodersAndSanitizers","type":"address[]"},{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"bytes[]","name":"targetData","type":"bytes[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"manageVaultWithMerkleVerification","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"feeAmounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"receiveFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategist","type":"address"},{"internalType":"bytes32","name":"_manageRoot","type":"bytes32"}],"name":"setManageRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract BoringVault","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c06040525f60045534801562000014575f80fd5b506040516200223a3803806200223a8339810160408190526200003791620000f8565b5f80546001600160a01b0385166001600160a01b031991821681178355600180549092169091556040518592919033907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908490a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b76389980198905f90a350506001600160a01b039182166080521660a052506200013f565b80516001600160a01b0381168114620000f3575f80fd5b919050565b5f805f606084860312156200010b575f80fd5b6200011684620000dc565b92506200012660208501620000dc565b91506200013660408501620000dc565b90509250925092565b60805160a05161209b6200019f5f395f818160ee015281816107e3015281816109da0152610bed01525f8181610225015281816103da01528181610511015281816106170152818161076601528181610a8c0152610ccf015261209b5ff3fe608060405234801561000f575f80fd5b50600436106100e5575f3560e01c80638456cb5911610088578063bf7e214f11610063578063bf7e214f146101e7578063f04f2707146101fa578063f2fde38b1461020d578063fbfa77cf14610220575f80fd5b80638456cb59146101b05780638da5cb5b146101b8578063b187bd26146101ca575f80fd5b80633f4ba83a116100c35780633f4ba83a146101555780635c38449e1461015d5780635ca58a99146101705780637a9e5e4b1461019d575f80fd5b8063158274a5146100e957806321801a991461012d578063244b0f6a14610142575b5f80fd5b6101107f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61014061013b36600461128e565b610247565b005b6101406101503660046112ff565b6102df565b6101406106f6565b61014061016b366004611421565b61075b565b61018f61017e3660046114c5565b60026020525f908152604090205481565b604051908152602001610124565b6101406101ab3660046114c5565b610883565b610140610967565b5f54610110906001600160a01b031681565b6005546101d79060ff1681565b6040519015158152602001610124565b600154610110906001600160a01b031681565b6101406102083660046114e0565b6109cf565b61014061021b3660046114c5565b610da7565b6101107f000000000000000000000000000000000000000000000000000000000000000081565b61025c335f356001600160e01b031916610e22565b6102815760405162461bcd60e51b81526004016102789061159a565b60405180910390fd5b6001600160a01b0382165f81815260026020908152604091829020805490859055825181815291820185905292917f0b958dec85f1470000479dfb22c365829411f52bcde602d24ea0abf5ac7e8860910160405180910390a2505050565b6102f4335f356001600160e01b031916610e22565b6103105760405162461bcd60e51b81526004016102789061159a565b60055460ff161561033457604051631b7b196560e31b815260040160405180910390fd5b848981146103555760405163029c70cf60e41b815260040160405180910390fd5b8084146103755760405163581ddbfd60e01b815260040160405180910390fd5b8082146103955760405163e9fd1adf60e01b815260040160405180910390fd5b8088146103b557604051631b4d824d60e31b815260040160405180910390fd5b335f9081526002602090815260408083205481516318160ddd60e01b815291519093927f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316926318160ddd92600480830193928290030181865afa158015610427573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061044b91906115c0565b90505f5b838110156106145761050f838f8f8481811061046d5761046d6115d7565b905060200281019061047f91906115eb565b8f8f86818110610491576104916115d7565b90506020020160208101906104a691906114c5565b8e8e878181106104b8576104b86115d7565b90506020020160208101906104cd91906114c5565b8b8b888181106104df576104df6115d7565b905060200201358e8e898181106104f8576104f86115d7565b905060200281019061050a9190611630565b610eca565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f6e715d08b8b84818110610550576105506115d7565b905060200201602081019061056591906114c5565b8a8a85818110610577576105776115d7565b90506020028101906105899190611630565b8a8a8781811061059b5761059b6115d7565b905060200201356040518563ffffffff1660e01b81526004016105c1949392919061169a565b5f604051808303815f875af11580156105dc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261060391908101906117aa565b5061060d816117ef565b905061044f565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610671573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069591906115c0565b81146106b457604051630ecee17560e01b815260040160405180910390fd5b6040518381527f53d426e7d80bb2c8674d3b45577e2d464d423faad6531b21f95ac11ac18b1cb69060200160405180910390a150505050505050505050505050565b61070b335f356001600160e01b031916610e22565b6107275760405162461bcd60e51b81526004016102789061159a565b6005805460ff191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933905f90a1565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107a4576040516377ed816560e01b815260040160405180910390fd5b81816040516107b4929190611807565b60405190819003812060049081556003805460ff19166001179055632e1c224f60e11b82526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691635c38449e91610822918b918b918b918b918b918b918b910161185d565b5f604051808303815f87803b158015610839575f80fd5b505af115801561084b573d5f803e3d5ffd5b50506003805460ff1916905550506004541561087a57604051633de6ce8160e21b815260040160405180910390fd5b50505050505050565b5f546001600160a01b0316331480610914575060015460405163b700961360e01b81526001600160a01b039091169063b7009613906108d590339030906001600160e01b03195f3516906004016118d3565b602060405180830381865afa1580156108f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109149190611900565b61091c575f80fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b76389980198905f90a350565b61097c335f356001600160e01b031916610e22565b6109985760405162461bcd60e51b81526004016102789061159a565b6005805460ff191660011790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e752905f90a1565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a185760405163a38bce7f60e01b815260040160405180910390fd5b60035460ff16610a3b576040516326e6e2c760e01b815260040160405180910390fd5b5f8282604051610a4c929190611807565b604051809103902090506004548114610a7857604051631663f61360e01b815260040160405180910390fd5b5f60048190555b86811015610b0b57610afb7f0000000000000000000000000000000000000000000000000000000000000000898984818110610abd57610abd6115d7565b905060200201358c8c85818110610ad657610ad66115d7565b9050602002016020810190610aeb91906114c5565b6001600160a01b03169190610fb4565b610b04816117ef565b9050610a7f565b505f80808080610b1d87890189611b96565b60405163122587b560e11b815294995092975090955093509150309063244b0f6a90610b559088908890889088908890600401611d2e565b5f604051808303815f87803b158015610b6c575f80fd5b505af1158015610b7e573d5f803e3d5ffd5b5050505050505050505f878790506001600160401b03811115610ba357610ba36116cf565b604051908082528060200260200182016040528015610bd657816020015b6060815260200190600190039081610bc15790505b5090505f5b87811015610cc45763a9059cbb60e01b7f0000000000000000000000000000000000000000000000000000000000000000888884818110610c1e57610c1e6115d7565b905060200201358b8b85818110610c3757610c376115d7565b90506020020135610c489190611e09565b6040516001600160a01b0390921660248301526044820152606401604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050828281518110610ca857610ca86115d7565b602002602001018190525080610cbd906117ef565b9050610bdb565b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663224d87038b8b848b6001600160401b03811115610d0f57610d0f6116cf565b604051908082528060200260200182016040528015610d38578160200160208202803683370190505b506040518563ffffffff1660e01b8152600401610d589493929190611e1c565b5f604051808303815f875af1158015610d73573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d9a9190810190611e60565b5050505050505050505050565b610dbc335f356001600160e01b031916610e22565b610dd85760405162461bcd60e51b81526004016102789061159a565b5f80546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6001545f906001600160a01b03168015801590610ea9575060405163b700961360e01b81526001600160a01b0382169063b700961390610e6a908790309088906004016118d3565b602060405180830381865afa158015610e85573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea99190611900565b80610ec057505f546001600160a01b038581169116145b9150505b92915050565b5f610f1483838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250506001600160a01b038a1692915050611037565b806020019051810190610f2791906117aa565b90505f610f3484846110a9565b90506001600160a01b03811615610f6a578181604051602001610f58929190611f0a565b60405160208183030381529060405291505b610f838a8a8a898b8a610f7d8a8c611f3b565b89611163565b610fa8578584848760405163c0dcd1a760e01b8152600401610278949392919061169a565b50505050505050505050565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f5114161716915050806110315760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610278565b50505050565b60605f80846001600160a01b0316846040516110539190611f69565b5f60405180830381855afa9150503d805f811461108b576040519150601f19603f3d011682016040523d82523d5f602084013e611090565b606091505b50915091506110a08583836111b7565b95945050505050565b5f816044811061115c575f84846110c1602085611f84565b6110cc928290611f97565b6110d591611fbe565b60408051808201909152600f81526e111c9bdb99531a588b9d185c99d95d608a1b60209091015290507fc1b9dfe6c6d6343c26291b77edfcc5dbc62c3afa2ee72581da4e3cdbe96a0a4f810161115a578484611132603485611f84565b9061113e602086611f84565b9261114b93929190611f97565b61115491611fdb565b60601c92505b505b5092915050565b5f805f851190505f8688838787604051602001611184959493929190612009565b6040516020818303038152906040528051906020012090506111a88a8a8d84611216565b9b9a5050505050505050505050565b6060826111cc576111c78261124e565b61120f565b81511580156111e357506001600160a01b0384163b155b1561120c57604051639996b31560e01b81526001600160a01b0385166004820152602401610278565b50805b9392505050565b5f8315611246578360051b8501855b803580851160051b94855260209485185260405f2093018181106112255750505b501492915050565b80511561125e5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6001600160a01b0381168114611277575f80fd5b5f806040838503121561129f575f80fd5b82356112aa8161127a565b946020939093013593505050565b5f8083601f8401126112c8575f80fd5b5081356001600160401b038111156112de575f80fd5b6020830191508360208260051b85010111156112f8575f80fd5b9250929050565b5f805f805f805f805f8060a08b8d031215611318575f80fd5b8a356001600160401b038082111561132e575f80fd5b61133a8e838f016112b8565b909c509a5060208d0135915080821115611352575f80fd5b61135e8e838f016112b8565b909a50985060408d0135915080821115611376575f80fd5b6113828e838f016112b8565b909850965060608d013591508082111561139a575f80fd5b6113a68e838f016112b8565b909650945060808d01359150808211156113be575f80fd5b506113cb8d828e016112b8565b915080935050809150509295989b9194979a5092959850565b5f8083601f8401126113f4575f80fd5b5081356001600160401b0381111561140a575f80fd5b6020830191508360208285010111156112f8575f80fd5b5f805f805f805f6080888a031215611437575f80fd5b87356114428161127a565b965060208801356001600160401b038082111561145d575f80fd5b6114698b838c016112b8565b909850965060408a0135915080821115611481575f80fd5b61148d8b838c016112b8565b909650945060608a01359150808211156114a5575f80fd5b506114b28a828b016113e4565b989b979a50959850939692959293505050565b5f602082840312156114d5575f80fd5b813561120f8161127a565b5f805f805f805f806080898b0312156114f7575f80fd5b88356001600160401b038082111561150d575f80fd5b6115198c838d016112b8565b909a50985060208b0135915080821115611531575f80fd5b61153d8c838d016112b8565b909850965060408b0135915080821115611555575f80fd5b6115618c838d016112b8565b909650945060608b0135915080821115611579575f80fd5b506115868b828c016113e4565b999c989b5096995094979396929594505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b5f602082840312156115d0575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112611600575f80fd5b8301803591506001600160401b03821115611619575f80fd5b6020019150600581901b36038213156112f8575f80fd5b5f808335601e19843603018112611645575f80fd5b8301803591506001600160401b0382111561165e575f80fd5b6020019150368190038213156112f8575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b03851681526060602082018190525f906116be9083018587611672565b905082604083015295945050505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561170b5761170b6116cf565b604052919050565b5f6001600160401b0382111561172b5761172b6116cf565b50601f01601f191660200190565b5f5b8381101561175357818101518382015260200161173b565b50505f910152565b5f82601f83011261176a575f80fd5b815161177d61177882611713565b6116e3565b818152846020838601011115611791575f80fd5b6117a2826020830160208701611739565b949350505050565b5f602082840312156117ba575f80fd5b81516001600160401b038111156117cf575f80fd5b610ec08482850161175b565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611800576118006117db565b5060010190565b818382375f9101908152919050565b8183525f60208085019450825f5b858110156118525781356118378161127a565b6001600160a01b031687529582019590820190600101611824565b509495945050505050565b6001600160a01b03881681526080602082018190525f90611881908301888a611816565b82810360408401528581526001600160fb1b0386111561189f575f80fd5b8560051b8088602084013701828103602090810160608501526118c59082018587611672565b9a9950505050505050505050565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b5f60208284031215611910575f80fd5b8151801515811461120f575f80fd5b5f6001600160401b03821115611937576119376116cf565b5060051b60200190565b5f82601f830112611950575f80fd5b813560206119606117788361191f565b828152600592831b850182019282820191908785111561197e575f80fd5b8387015b85811015611a0e5780356001600160401b038111156119a0575f8081fd5b8801603f81018a136119b1575f8081fd5b8581013560406119c36117788361191f565b82815291851b8301810191888101908d8411156119df575f8081fd5b938201935b838510156119fd578435825293890193908901906119e4565b885250505093850193508401611982565b5090979650505050505050565b5f82601f830112611a2a575f80fd5b81356020611a3a6117788361191f565b82815260059290921b84018101918181019086841115611a58575f80fd5b8286015b84811015611a7c578035611a6f8161127a565b8352918301918301611a5c565b509695505050505050565b5f82601f830112611a96575f80fd5b81356020611aa66117788361191f565b82815260059290921b84018101918181019086841115611ac4575f80fd5b8286015b84811015611a7c5780356001600160401b03811115611ae6575f8081fd5b8701603f81018913611af7575f8081fd5b848101356040611b0961177883611713565b8281528b82848601011115611b1d575f8081fd5b82828501898301375f92810188019290925250845250918301918301611ac8565b5f82601f830112611b4d575f80fd5b81356020611b5d6117788361191f565b82815260059290921b84018101918181019086841115611b7b575f80fd5b8286015b84811015611a7c5780358352918301918301611b7f565b5f805f805f60a08688031215611baa575f80fd5b85356001600160401b0380821115611bc0575f80fd5b611bcc89838a01611941565b96506020880135915080821115611be1575f80fd5b611bed89838a01611a1b565b95506040880135915080821115611c02575f80fd5b611c0e89838a01611a1b565b94506060880135915080821115611c23575f80fd5b611c2f89838a01611a87565b93506080880135915080821115611c44575f80fd5b50611c5188828901611b3e565b9150509295509295909350565b5f8151808452602080850194508084015f5b838110156118525781516001600160a01b031687529582019590820190600101611c70565b5f81518084526020808501808196508360051b810191508286015f5b85811015611cf357828403895281518051808652611cd481888801898501611739565b99860199601f01601f1916949094018501935090840190600101611cb1565b5091979650505050505050565b5f8151808452602080850194508084015f5b8381101561185257815187529582019590820190600101611d12565b5f60a0820160a0835280885180835260c08501915060c08160051b86010192506020808b015f805b84811015611daa5788870360bf19018652825180518089529085019085890190845b81811015611d9457835183529287019291870191600101611d78565b5090985050509483019491830191600101611d56565b50505085840381870152505050611dc18188611c5e565b90508281036040840152611dd58187611c5e565b90508281036060840152611de98186611c95565b90508281036080840152611dfd8185611d00565b98975050505050505050565b80820180821115610ec457610ec46117db565b606081525f611e2f606083018688611816565b8281036020840152611e418186611c95565b90508281036040840152611e558185611d00565b979650505050505050565b5f6020808385031215611e71575f80fd5b82516001600160401b0380821115611e87575f80fd5b818501915085601f830112611e9a575f80fd5b8151611ea86117788261191f565b81815260059190911b83018401908481019088831115611ec6575f80fd5b8585015b83811015611efd57805185811115611ee1575f8081fd5b611eef8b89838a010161175b565b845250918601918601611eca565b5098975050505050505050565b5f8351611f1b818460208801611739565b60609390931b6001600160601b0319169190920190815260140192915050565b6001600160e01b0319813581811691600485101561115a5760049490940360031b84901b1690921692915050565b5f8251611f7a818460208701611739565b9190910192915050565b81810381811115610ec457610ec46117db565b5f8085851115611fa5575f80fd5b83861115611fb1575f80fd5b5050820193919092039150565b80356020831015610ec4575f19602084900360031b1b1692915050565b6001600160601b0319813581811691601485101561115a5760149490940360031b84901b1690921692915050565b6001600160601b0319606087811b8216835286901b16601482015283151560f81b60288201526001600160e01b03198316602982015281515f9061205481602d850160208701611739565b91909101602d01969550505050505056fea2646970667358221220b661740067ab467704e88cb26f410234913d6239ae08b024f801c9749150d9e764736f6c63430008150033000000000000000000000000771263e3bc6acda5ae388a3f8a0c2dd7a17275fc000000000000000000000000279cad277447965af3d24a78197aad1b02a2c589000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100e5575f3560e01c80638456cb5911610088578063bf7e214f11610063578063bf7e214f146101e7578063f04f2707146101fa578063f2fde38b1461020d578063fbfa77cf14610220575f80fd5b80638456cb59146101b05780638da5cb5b146101b8578063b187bd26146101ca575f80fd5b80633f4ba83a116100c35780633f4ba83a146101555780635c38449e1461015d5780635ca58a99146101705780637a9e5e4b1461019d575f80fd5b8063158274a5146100e957806321801a991461012d578063244b0f6a14610142575b5f80fd5b6101107f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c881565b6040516001600160a01b0390911681526020015b60405180910390f35b61014061013b36600461128e565b610247565b005b6101406101503660046112ff565b6102df565b6101406106f6565b61014061016b366004611421565b61075b565b61018f61017e3660046114c5565b60026020525f908152604090205481565b604051908152602001610124565b6101406101ab3660046114c5565b610883565b610140610967565b5f54610110906001600160a01b031681565b6005546101d79060ff1681565b6040519015158152602001610124565b600154610110906001600160a01b031681565b6101406102083660046114e0565b6109cf565b61014061021b3660046114c5565b610da7565b6101107f000000000000000000000000279cad277447965af3d24a78197aad1b02a2c58981565b61025c335f356001600160e01b031916610e22565b6102815760405162461bcd60e51b81526004016102789061159a565b60405180910390fd5b6001600160a01b0382165f81815260026020908152604091829020805490859055825181815291820185905292917f0b958dec85f1470000479dfb22c365829411f52bcde602d24ea0abf5ac7e8860910160405180910390a2505050565b6102f4335f356001600160e01b031916610e22565b6103105760405162461bcd60e51b81526004016102789061159a565b60055460ff161561033457604051631b7b196560e31b815260040160405180910390fd5b848981146103555760405163029c70cf60e41b815260040160405180910390fd5b8084146103755760405163581ddbfd60e01b815260040160405180910390fd5b8082146103955760405163e9fd1adf60e01b815260040160405180910390fd5b8088146103b557604051631b4d824d60e31b815260040160405180910390fd5b335f9081526002602090815260408083205481516318160ddd60e01b815291519093927f000000000000000000000000279cad277447965af3d24a78197aad1b02a2c5896001600160a01b0316926318160ddd92600480830193928290030181865afa158015610427573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061044b91906115c0565b90505f5b838110156106145761050f838f8f8481811061046d5761046d6115d7565b905060200281019061047f91906115eb565b8f8f86818110610491576104916115d7565b90506020020160208101906104a691906114c5565b8e8e878181106104b8576104b86115d7565b90506020020160208101906104cd91906114c5565b8b8b888181106104df576104df6115d7565b905060200201358e8e898181106104f8576104f86115d7565b905060200281019061050a9190611630565b610eca565b7f000000000000000000000000279cad277447965af3d24a78197aad1b02a2c5896001600160a01b031663f6e715d08b8b84818110610550576105506115d7565b905060200201602081019061056591906114c5565b8a8a85818110610577576105776115d7565b90506020028101906105899190611630565b8a8a8781811061059b5761059b6115d7565b905060200201356040518563ffffffff1660e01b81526004016105c1949392919061169a565b5f604051808303815f875af11580156105dc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261060391908101906117aa565b5061060d816117ef565b905061044f565b507f000000000000000000000000279cad277447965af3d24a78197aad1b02a2c5896001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610671573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069591906115c0565b81146106b457604051630ecee17560e01b815260040160405180910390fd5b6040518381527f53d426e7d80bb2c8674d3b45577e2d464d423faad6531b21f95ac11ac18b1cb69060200160405180910390a150505050505050505050505050565b61070b335f356001600160e01b031916610e22565b6107275760405162461bcd60e51b81526004016102789061159a565b6005805460ff191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933905f90a1565b336001600160a01b037f000000000000000000000000279cad277447965af3d24a78197aad1b02a2c58916146107a4576040516377ed816560e01b815260040160405180910390fd5b81816040516107b4929190611807565b60405190819003812060049081556003805460ff19166001179055632e1c224f60e11b82526001600160a01b037f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c81691635c38449e91610822918b918b918b918b918b918b918b910161185d565b5f604051808303815f87803b158015610839575f80fd5b505af115801561084b573d5f803e3d5ffd5b50506003805460ff1916905550506004541561087a57604051633de6ce8160e21b815260040160405180910390fd5b50505050505050565b5f546001600160a01b0316331480610914575060015460405163b700961360e01b81526001600160a01b039091169063b7009613906108d590339030906001600160e01b03195f3516906004016118d3565b602060405180830381865afa1580156108f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109149190611900565b61091c575f80fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b76389980198905f90a350565b61097c335f356001600160e01b031916610e22565b6109985760405162461bcd60e51b81526004016102789061159a565b6005805460ff191660011790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e752905f90a1565b336001600160a01b037f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c81614610a185760405163a38bce7f60e01b815260040160405180910390fd5b60035460ff16610a3b576040516326e6e2c760e01b815260040160405180910390fd5b5f8282604051610a4c929190611807565b604051809103902090506004548114610a7857604051631663f61360e01b815260040160405180910390fd5b5f60048190555b86811015610b0b57610afb7f000000000000000000000000279cad277447965af3d24a78197aad1b02a2c589898984818110610abd57610abd6115d7565b905060200201358c8c85818110610ad657610ad66115d7565b9050602002016020810190610aeb91906114c5565b6001600160a01b03169190610fb4565b610b04816117ef565b9050610a7f565b505f80808080610b1d87890189611b96565b60405163122587b560e11b815294995092975090955093509150309063244b0f6a90610b559088908890889088908890600401611d2e565b5f604051808303815f87803b158015610b6c575f80fd5b505af1158015610b7e573d5f803e3d5ffd5b5050505050505050505f878790506001600160401b03811115610ba357610ba36116cf565b604051908082528060200260200182016040528015610bd657816020015b6060815260200190600190039081610bc15790505b5090505f5b87811015610cc45763a9059cbb60e01b7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8888884818110610c1e57610c1e6115d7565b905060200201358b8b85818110610c3757610c376115d7565b90506020020135610c489190611e09565b6040516001600160a01b0390921660248301526044820152606401604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050828281518110610ca857610ca86115d7565b602002602001018190525080610cbd906117ef565b9050610bdb565b506001600160a01b037f000000000000000000000000279cad277447965af3d24a78197aad1b02a2c5891663224d87038b8b848b6001600160401b03811115610d0f57610d0f6116cf565b604051908082528060200260200182016040528015610d38578160200160208202803683370190505b506040518563ffffffff1660e01b8152600401610d589493929190611e1c565b5f604051808303815f875af1158015610d73573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d9a9190810190611e60565b5050505050505050505050565b610dbc335f356001600160e01b031916610e22565b610dd85760405162461bcd60e51b81526004016102789061159a565b5f80546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6001545f906001600160a01b03168015801590610ea9575060405163b700961360e01b81526001600160a01b0382169063b700961390610e6a908790309088906004016118d3565b602060405180830381865afa158015610e85573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea99190611900565b80610ec057505f546001600160a01b038581169116145b9150505b92915050565b5f610f1483838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250506001600160a01b038a1692915050611037565b806020019051810190610f2791906117aa565b90505f610f3484846110a9565b90506001600160a01b03811615610f6a578181604051602001610f58929190611f0a565b60405160208183030381529060405291505b610f838a8a8a898b8a610f7d8a8c611f3b565b89611163565b610fa8578584848760405163c0dcd1a760e01b8152600401610278949392919061169a565b50505050505050505050565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f5114161716915050806110315760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610278565b50505050565b60605f80846001600160a01b0316846040516110539190611f69565b5f60405180830381855afa9150503d805f811461108b576040519150601f19603f3d011682016040523d82523d5f602084013e611090565b606091505b50915091506110a08583836111b7565b95945050505050565b5f816044811061115c575f84846110c1602085611f84565b6110cc928290611f97565b6110d591611fbe565b60408051808201909152600f81526e111c9bdb99531a588b9d185c99d95d608a1b60209091015290507fc1b9dfe6c6d6343c26291b77edfcc5dbc62c3afa2ee72581da4e3cdbe96a0a4f810161115a578484611132603485611f84565b9061113e602086611f84565b9261114b93929190611f97565b61115491611fdb565b60601c92505b505b5092915050565b5f805f851190505f8688838787604051602001611184959493929190612009565b6040516020818303038152906040528051906020012090506111a88a8a8d84611216565b9b9a5050505050505050505050565b6060826111cc576111c78261124e565b61120f565b81511580156111e357506001600160a01b0384163b155b1561120c57604051639996b31560e01b81526001600160a01b0385166004820152602401610278565b50805b9392505050565b5f8315611246578360051b8501855b803580851160051b94855260209485185260405f2093018181106112255750505b501492915050565b80511561125e5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6001600160a01b0381168114611277575f80fd5b5f806040838503121561129f575f80fd5b82356112aa8161127a565b946020939093013593505050565b5f8083601f8401126112c8575f80fd5b5081356001600160401b038111156112de575f80fd5b6020830191508360208260051b85010111156112f8575f80fd5b9250929050565b5f805f805f805f805f8060a08b8d031215611318575f80fd5b8a356001600160401b038082111561132e575f80fd5b61133a8e838f016112b8565b909c509a5060208d0135915080821115611352575f80fd5b61135e8e838f016112b8565b909a50985060408d0135915080821115611376575f80fd5b6113828e838f016112b8565b909850965060608d013591508082111561139a575f80fd5b6113a68e838f016112b8565b909650945060808d01359150808211156113be575f80fd5b506113cb8d828e016112b8565b915080935050809150509295989b9194979a5092959850565b5f8083601f8401126113f4575f80fd5b5081356001600160401b0381111561140a575f80fd5b6020830191508360208285010111156112f8575f80fd5b5f805f805f805f6080888a031215611437575f80fd5b87356114428161127a565b965060208801356001600160401b038082111561145d575f80fd5b6114698b838c016112b8565b909850965060408a0135915080821115611481575f80fd5b61148d8b838c016112b8565b909650945060608a01359150808211156114a5575f80fd5b506114b28a828b016113e4565b989b979a50959850939692959293505050565b5f602082840312156114d5575f80fd5b813561120f8161127a565b5f805f805f805f806080898b0312156114f7575f80fd5b88356001600160401b038082111561150d575f80fd5b6115198c838d016112b8565b909a50985060208b0135915080821115611531575f80fd5b61153d8c838d016112b8565b909850965060408b0135915080821115611555575f80fd5b6115618c838d016112b8565b909650945060608b0135915080821115611579575f80fd5b506115868b828c016113e4565b999c989b5096995094979396929594505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b5f602082840312156115d0575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112611600575f80fd5b8301803591506001600160401b03821115611619575f80fd5b6020019150600581901b36038213156112f8575f80fd5b5f808335601e19843603018112611645575f80fd5b8301803591506001600160401b0382111561165e575f80fd5b6020019150368190038213156112f8575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b03851681526060602082018190525f906116be9083018587611672565b905082604083015295945050505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561170b5761170b6116cf565b604052919050565b5f6001600160401b0382111561172b5761172b6116cf565b50601f01601f191660200190565b5f5b8381101561175357818101518382015260200161173b565b50505f910152565b5f82601f83011261176a575f80fd5b815161177d61177882611713565b6116e3565b818152846020838601011115611791575f80fd5b6117a2826020830160208701611739565b949350505050565b5f602082840312156117ba575f80fd5b81516001600160401b038111156117cf575f80fd5b610ec08482850161175b565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611800576118006117db565b5060010190565b818382375f9101908152919050565b8183525f60208085019450825f5b858110156118525781356118378161127a565b6001600160a01b031687529582019590820190600101611824565b509495945050505050565b6001600160a01b03881681526080602082018190525f90611881908301888a611816565b82810360408401528581526001600160fb1b0386111561189f575f80fd5b8560051b8088602084013701828103602090810160608501526118c59082018587611672565b9a9950505050505050505050565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b5f60208284031215611910575f80fd5b8151801515811461120f575f80fd5b5f6001600160401b03821115611937576119376116cf565b5060051b60200190565b5f82601f830112611950575f80fd5b813560206119606117788361191f565b828152600592831b850182019282820191908785111561197e575f80fd5b8387015b85811015611a0e5780356001600160401b038111156119a0575f8081fd5b8801603f81018a136119b1575f8081fd5b8581013560406119c36117788361191f565b82815291851b8301810191888101908d8411156119df575f8081fd5b938201935b838510156119fd578435825293890193908901906119e4565b885250505093850193508401611982565b5090979650505050505050565b5f82601f830112611a2a575f80fd5b81356020611a3a6117788361191f565b82815260059290921b84018101918181019086841115611a58575f80fd5b8286015b84811015611a7c578035611a6f8161127a565b8352918301918301611a5c565b509695505050505050565b5f82601f830112611a96575f80fd5b81356020611aa66117788361191f565b82815260059290921b84018101918181019086841115611ac4575f80fd5b8286015b84811015611a7c5780356001600160401b03811115611ae6575f8081fd5b8701603f81018913611af7575f8081fd5b848101356040611b0961177883611713565b8281528b82848601011115611b1d575f8081fd5b82828501898301375f92810188019290925250845250918301918301611ac8565b5f82601f830112611b4d575f80fd5b81356020611b5d6117788361191f565b82815260059290921b84018101918181019086841115611b7b575f80fd5b8286015b84811015611a7c5780358352918301918301611b7f565b5f805f805f60a08688031215611baa575f80fd5b85356001600160401b0380821115611bc0575f80fd5b611bcc89838a01611941565b96506020880135915080821115611be1575f80fd5b611bed89838a01611a1b565b95506040880135915080821115611c02575f80fd5b611c0e89838a01611a1b565b94506060880135915080821115611c23575f80fd5b611c2f89838a01611a87565b93506080880135915080821115611c44575f80fd5b50611c5188828901611b3e565b9150509295509295909350565b5f8151808452602080850194508084015f5b838110156118525781516001600160a01b031687529582019590820190600101611c70565b5f81518084526020808501808196508360051b810191508286015f5b85811015611cf357828403895281518051808652611cd481888801898501611739565b99860199601f01601f1916949094018501935090840190600101611cb1565b5091979650505050505050565b5f8151808452602080850194508084015f5b8381101561185257815187529582019590820190600101611d12565b5f60a0820160a0835280885180835260c08501915060c08160051b86010192506020808b015f805b84811015611daa5788870360bf19018652825180518089529085019085890190845b81811015611d9457835183529287019291870191600101611d78565b5090985050509483019491830191600101611d56565b50505085840381870152505050611dc18188611c5e565b90508281036040840152611dd58187611c5e565b90508281036060840152611de98186611c95565b90508281036080840152611dfd8185611d00565b98975050505050505050565b80820180821115610ec457610ec46117db565b606081525f611e2f606083018688611816565b8281036020840152611e418186611c95565b90508281036040840152611e558185611d00565b979650505050505050565b5f6020808385031215611e71575f80fd5b82516001600160401b0380821115611e87575f80fd5b818501915085601f830112611e9a575f80fd5b8151611ea86117788261191f565b81815260059190911b83018401908481019088831115611ec6575f80fd5b8585015b83811015611efd57805185811115611ee1575f8081fd5b611eef8b89838a010161175b565b845250918601918601611eca565b5098975050505050505050565b5f8351611f1b818460208801611739565b60609390931b6001600160601b0319169190920190815260140192915050565b6001600160e01b0319813581811691600485101561115a5760049490940360031b84901b1690921692915050565b5f8251611f7a818460208701611739565b9190910192915050565b81810381811115610ec457610ec46117db565b5f8085851115611fa5575f80fd5b83861115611fb1575f80fd5b5050820193919092039150565b80356020831015610ec4575f19602084900360031b1b1692915050565b6001600160601b0319813581811691601485101561115a5760149490940360031b84901b1690921692915050565b6001600160601b0319606087811b8216835286901b16601482015283151560f81b60288201526001600160e01b03198316602982015281515f9061205481602d850160208701611739565b91909101602d01969550505050505056fea2646970667358221220b661740067ab467704e88cb26f410234913d6239ae08b024f801c9749150d9e764736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000771263e3bc6acda5ae388a3f8a0c2dd7a17275fc000000000000000000000000279cad277447965af3d24a78197aad1b02a2c589000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
-----Decoded View---------------
Arg [0] : _owner (address): 0x771263e3Bc6aCDa5aE388A3F8A0c2dd7A17275FC
Arg [1] : _vault (address): 0x279CAD277447965AF3d24a78197aad1B02a2c589
Arg [2] : _balancerVault (address): 0xBA12222222228d8Ba445958a75a0704d566BF2C8
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000771263e3bc6acda5ae388a3f8a0c2dd7a17275fc
Arg [1] : 000000000000000000000000279cad277447965af3d24a78197aad1b02a2c589
Arg [2] : 000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
Loading...
Loading
Loading...
Loading
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.