Description:
Decentralized Finance (DeFi) protocol contract providing Liquidity, Yield, Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"@openzeppelin/contracts/math/SafeMath.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
"
},
"@openzeppelin/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
"
},
"@uniswap/v3-periphery/contracts/libraries/BytesLib.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later
/*
* @title Solidity Bytes Arrays Utils
* @author Gonçalo Sá <goncalo.sa@consensys.net>
*
* @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
* The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
*/
pragma solidity >=0.5.0 <0.8.0;
library BytesLib {
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
) internal pure returns (bytes memory) {
require(_length + 31 >= _length, 'slice_overflow');
require(_start + _length >= _start, 'slice_overflow');
require(_bytes.length >= _start + _length, 'slice_outOfBounds');
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_start + 20 >= _start, 'toAddress_overflow');
require(_bytes.length >= _start + 20, 'toAddress_outOfBounds');
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {
require(_start + 3 >= _start, 'toUint24_overflow');
require(_bytes.length >= _start + 3, 'toUint24_outOfBounds');
uint24 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x3), _start))
}
return tempUint;
}
}
"
},
"contracts/guards/assetGuards/ERC20Guard.sol": {
"content": "//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2025 dHEDGE DAO
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {TxDataUtils} from "../../utils/TxDataUtils.sol";
import {IAssetGuard} from "../../interfaces/guards/IAssetGuard.sol";
import {IGuard} from "../../interfaces/guards/IGuard.sol";
import {IERC20Extended} from "../../interfaces/IERC20Extended.sol";
import {IPoolLogic} from "../../interfaces/IPoolLogic.sol";
import {IPoolManagerLogic} from "../../interfaces/IPoolManagerLogic.sol";
import {IHasGuardInfo} from "../../interfaces/IHasGuardInfo.sol";
import {IHasSupportedAsset} from "../../interfaces/IHasSupportedAsset.sol";
import {ITransactionTypes} from "../../interfaces/ITransactionTypes.sol";
import {IAaveLendingPoolAssetGuard} from "../../interfaces/guards/IAaveLendingPoolAssetGuard.sol";
import {IGovernance} from "../../interfaces/IGovernance.sol";
import {IPoolFactory} from "../../interfaces/IPoolFactory.sol";
import {IAaveV3Pool} from "../../interfaces/aave/v3/IAaveV3Pool.sol";
/// @title Generic ERC20 asset guard
/// @dev Asset type = 0
contract ERC20Guard is TxDataUtils, IGuard, IAssetGuard, ITransactionTypes {
using SafeMath for uint256;
/// @notice Transaction guard for approving assets
/// @dev Parses the manager transaction data to ensure transaction is valid
/// @param poolManagerLogic PoolManagerLogic address
/// @param data Transaction call data attempt by manager
/// @return txType transaction type described in ITransactionTypes
/// @return isPublic if the transaction is public or private
function txGuard(
address poolManagerLogic,
address /* to */,
bytes calldata data
) external view override returns (uint16 txType, bool) {
bytes4 method = getMethod(data);
if (method == bytes4(keccak256("approve(address,uint256)"))) {
address spender = convert32toAddress(getInput(data, 0));
address factory = IPoolManagerLogic(poolManagerLogic).factory();
address spenderGuard = IHasGuardInfo(factory).getContractGuard(spender);
require(spenderGuard != address(0) && spenderGuard != address(this), "unsupported spender approval"); // checks that the spender is an approved address
txType = uint16(TransactionType.Approve);
}
return (txType, false);
}
/// @notice Withdraw processing for ERC20 asset
/// @param pool Address of the pool
/// @param asset Address of the managed asset
/// @param portion Portion of the asset balance to withdraw, in 10^18 scale
/// @return withdrawAsset and
/// @return withdrawBalance are used to withdraw portion of asset balance to depositor
/// @return transactions are used to execute the withdrawal transactions in PoolLogic
function withdrawProcessing(
address pool,
address asset,
uint256 portion,
address /* to */
)
external
virtual
override
returns (address withdrawAsset, uint256 withdrawBalance, MultiTransaction[] memory transactions)
{
withdrawAsset = asset;
uint256 totalAssetBalance = getBalance(pool, asset);
withdrawBalance = totalAssetBalance.mul(portion).div(10 ** 18);
return (withdrawAsset, withdrawBalance, transactions);
}
/// @notice Returns the balance of the managed asset
/// @param pool Address of the pool
/// @param asset Address of the managed asset
/// @return balance The asset balance of given pool
function getBalance(address pool, address asset) public view virtual override returns (uint256 balance) {
// The base ERC20 guard has no externally staked tokens
balance = IERC20(asset).balanceOf(pool);
}
/// @notice Returns the decimal of the managed asset
/// @param asset Address of the managed asset
/// @return decimals The decimal of given asset
function getDecimals(address asset) external view virtual override returns (uint256 decimals) {
decimals = IERC20Extended(asset).decimals();
}
/// @notice Necessary check for remove asset.
/// In AaveLendingPoolAssetGuard, when calculating getBalance, the function loops through all the supported assets.
/// Supported asset balance can be 0, but aave collateral or debt can be > 0. If it was able to remove the asset,
/// the value of Aave lending pool position would become lower. Having this asset guard with removeAssetCheck prevents this.
/// If there is any collateral or debt of a particular asset in Aave, it's not possible to remove that asset.
/// @param pool Address of the pool
/// @param asset Address of the remove asset
function removeAssetCheck(address pool, address asset) public view virtual override {
require(getBalance(pool, asset) == 0, "cannot remove non-empty asset");
address factory = IPoolLogic(pool).factory();
address governance = IPoolFactory(factory).governanceAddress();
// Magic number 8 is Aave lending pool "asset" asset type
address aaveLendingPoolAssetGuard = IGovernance(governance).assetGuards(8);
if (aaveLendingPoolAssetGuard == address(0)) {
// If Aave lending pool asset guard is not set, skip the check
return;
}
address aaveLendingPool = IAaveLendingPoolAssetGuard(aaveLendingPoolAssetGuard).aaveLendingPool();
if (!IHasSupportedAsset(IPoolLogic(pool).poolManagerLogic()).isSupportedAsset(aaveLendingPool)) {
// If Aave lending pool asset is not supported, skip the check
return;
}
// Returns address(0) if it's not supported in Aave
address variableDebtToken = IAaveV3Pool(aaveLendingPool).getReserveVariableDebtToken(asset);
if (variableDebtToken != address(0))
require(IERC20(variableDebtToken).balanceOf(pool) == 0, "repay Aave debt first");
// Returns address(0) if it's not supported in Aave
address aToken = IAaveV3Pool(aaveLendingPool).getReserveAToken(asset);
if (aToken != address(0)) require(IERC20(aToken).balanceOf(pool) == 0, "withdraw Aave collateral first");
}
}
"
},
"contracts/guards/assetGuards/pendle/PendlePTAssetGuard.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {IHasSupportedAsset} from "../../../interfaces/IHasSupportedAsset.sol";
import {IAddAssetCheckGuard} from "../../../interfaces/guards/IAddAssetCheckGuard.sol";
import {IPMarketFactoryV3} from "../../../interfaces/pendle/IPMarketFactoryV3.sol";
import {IPMarket} from "../../../interfaces/pendle/IPMarket.sol";
import {IStandardizedYield} from "../../../interfaces/pendle/IStandardizedYield.sol";
import {ERC20Guard} from "../ERC20Guard.sol";
/// @notice Core features are identical to ERC20Guard, with the addition of onchain storage for PT associated data, to workaround unrolling PTs during single assset withdrawals
/// @dev Asset type = 37
contract PendlePTAssetGuard is ERC20Guard, IAddAssetCheckGuard {
struct PTAssociatedData {
address market;
address yieldToken;
address yt;
}
bool public override isAddAssetCheckGuard = true;
IPMarketFactoryV3 public immutable pendleMarketFactoryV3;
mapping(address => PTAssociatedData) public ptAssociatedData;
constructor(address _pendleMarketFactoryV3, address[] memory _knownPendleMarkets) {
require(_pendleMarketFactoryV3 != address(0), "invalid market factory");
pendleMarketFactoryV3 = IPMarketFactoryV3(_pendleMarketFactoryV3);
for (uint256 i; i < _knownPendleMarkets.length; ++i) {
require(IPMarketFactoryV3(_pendleMarketFactoryV3).isValidMarket(_knownPendleMarkets[i]), "invalid market");
(address sy, address pt, address yt) = IPMarket(_knownPendleMarkets[i]).readTokens();
ptAssociatedData[pt] = PTAssociatedData({
market: _knownPendleMarkets[i],
yieldToken: IStandardizedYield(sy).yieldToken(),
yt: yt
});
}
}
function addAssetCheck(address, IHasSupportedAsset.Asset calldata _asset) external view override {
PTAssociatedData memory ptData = ptAssociatedData[_asset.asset];
require(ptData.market != address(0), "unknown PT");
}
}
"
},
"contracts/interfaces/aave/v3/DataTypes.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
library DataTypes {
/**
* This exists specifically to maintain the `getReserveData()` interface, since the new, internal
* `ReserveData` struct includes the reserve's `virtualUnderlyingBalance`.
*/
struct ReserveDataLegacy {
//stores the reserve configuration
ReserveConfigurationMap configuration;
//the liquidity index. Expressed in ray
uint128 liquidityIndex;
//the current supply rate. Expressed in ray
uint128 currentLiquidityRate;
//variable borrow index. Expressed in ray
uint128 variableBorrowIndex;
//the current variable borrow rate. Expressed in ray
uint128 currentVariableBorrowRate;
// DEPRECATED on v3.2.0
uint128 currentStableBorrowRate;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//aToken address
address aTokenAddress;
// DEPRECATED on v3.2.0
address stableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
//address of the interest rate strategy
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
//the outstanding unbacked aTokens minted through the bridging feature
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
}
struct ReserveConfigurationMap {
//bit 0-15: LTV
//bit 16-31: Liq. threshold
//bit 32-47: Liq. bonus
//bit 48-55: Decimals
//bit 56: reserve is active
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: DEPRECATED: stable rate borrowing enabled
//bit 60: asset is paused
//bit 61: borrowing in isolation mode is enabled
//bit 62: siloed borrowing enabled
//bit 63: flashloaning enabled
//bit 64-79: reserve factor
//bit 80-115: borrow cap in whole tokens, borrowCap == 0 => no cap
//bit 116-151: supply cap in whole tokens, supplyCap == 0 => no cap
//bit 152-167: liquidation protocol fee
//bit 168-175: DEPRECATED: eMode category
//bit 176-211: unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
//bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
//bit 252: virtual accounting is enabled for the reserve
//bit 253-255 unused
uint256 data;
}
/**
* @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset.
* The first bit indicates if an asset is used as collateral by the user, the second whether an
* asset is borrowed by the user.
*/
struct UserConfigurationMap {
uint256 data;
}
}
"
},
"contracts/interfaces/aave/v3/IAaveV3Pool.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {DataTypes} from "./DataTypes.sol";
/**
* @title IPool
* @author Aave
* @notice Defines the basic interface for an Aave Pool.
*/
interface IAaveV3Pool {
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
/**
* @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
* E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
* @param asset The address of the underlying asset to withdraw
* @param amount The underlying amount to be withdrawn
* - Send the value type(uint256).max in order to withdraw the whole aToken balance
* @param to The address that will receive the underlying, same as msg.sender if the user
* wants to receive it on his own wallet, or a different address if the beneficiary is a
* different wallet
* @return The final amount withdrawn
*/
function withdraw(address asset, uint256 amount, address to) external returns (uint256);
/**
* @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
* already supplied enough collateral, or he was given enough allowance by a credit delegator on the VariableDebtToken
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* and 100 variable debt tokens
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself
* calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
* if he has been given credit delegation allowance
*/
function borrow(
address asset,
uint256 amount,
uint256 interestRateMode,
uint16 referralCode,
address onBehalfOf
) external;
/**
* @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
* - E.g. User repays 100 USDC, burning 100 variable debt tokens of the `onBehalfOf` address
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @return The final amount repaid
*/
function repay(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf
) external returns (uint256);
/**
* @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the
* equivalent debt tokens
* - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable debt tokens
* @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken
* balance is not enough to cover the whole debt
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode DEPRECATED in v3.2.0
* @return The final amount repaid
*/
function repayWithATokens(address asset, uint256 amount, uint256 interestRateMode) external returns (uint256);
/**
* @notice Allows suppliers to enable/disable a specific supplied asset as collateral
* @param asset The address of the underlying asset supplied
* @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise
*/
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;
/**
* @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
*/
function liquidationCall(
address collateralAsset,
address debtAsset,
address user,
uint256 debtToCover,
bool receiveAToken
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface
* @param assets The addresses of the assets being flash-borrowed
* @param amounts The amounts of the assets being flash-borrowed
* @param interestRateModes Types of the debt to open if the flash loan is not returned:
* 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
* 1 -> Deprecated on v3.2.0
* 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* @param onBehalfOf The address that will receive the debt in the case of using 2 on `modes`
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoan(
address receiverAddress,
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata interestRateModes,
address onBehalfOf,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://docs.aave.com/developers/
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface
* @param asset The address of the asset being flash-borrowed
* @param amount The amount of the asset being flash-borrowed
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function flashLoanSimple(
address receiverAddress,
address asset,
uint256 amount,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Returns the user account data across all the reserves
* @param user The address of the user
* @return totalCollateralBase The total collateral of the user in the base currency used by the price feed
* @return totalDebtBase The total debt of the user in the base currency used by the price feed
* @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed
* @return currentLiquidationThreshold The liquidation threshold of the user
* @return ltv The loan to value of The user
* @return healthFactor The current health factor of the user
*/
function getUserAccountData(
address user
)
external
view
returns (
uint256 totalCollateralBase,
uint256 totalDebtBase,
uint256 availableBorrowsBase,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
);
/**
* @notice Returns the configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The configuration of the reserve
*/
function getConfiguration(address asset) external view returns (DataTypes.ReserveConfigurationMap memory);
/**
* @notice Returns the configuration of the user across all the reserves
* @param user The user address
* @return The configuration of the user
*/
function getUserConfiguration(address user) external view returns (DataTypes.UserConfigurationMap memory);
/**
* @notice Returns the state and configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The state and configuration data of the reserve
*/
function getReserveData(address asset) external view returns (DataTypes.ReserveDataLegacy memory);
/**
* @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct
* @param id The id of the reserve as stored in the DataTypes.ReserveData struct
* @return The address of the reserve associated with id
*/
function getReserveAddressById(uint16 id) external view returns (address);
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @dev Deprecated: Use the `supply` function instead
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
*/
function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
/**
* @notice Returns the aToken address of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The address of the aToken
*/
function getReserveAToken(address asset) external view returns (address);
/**
* @notice Returns the variableDebtToken address of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The address of the variableDebtToken
*/
function getReserveVariableDebtToken(address asset) external view returns (address);
/**
* @notice Allows a user to use the protocol in eMode
* @param categoryId The id of the category
*/
function setUserEMode(uint8 categoryId) external;
/**
* @notice Returns the eMode the user is using
* @param user The address of the user
* @return The eMode id
*/
function getUserEMode(address user) external view returns (uint256);
}
"
},
"contracts/interfaces/guards/IAaveLendingPoolAssetGuard.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {IAssetGuard} from "./IAssetGuard.sol";
interface IAaveLendingPoolAssetGuard {
function flashloanProcessing(
address pool,
address repayAsset,
uint256 repayAmount,
uint256 premium,
bytes calldata params
) external view returns (IAssetGuard.MultiTransaction[] memory transactions);
function aaveLendingPool() external view returns (address lendingPool);
}
"
},
"contracts/interfaces/guards/IAddAssetCheckGuard.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {IHasSupportedAsset} from "../IHasSupportedAsset.sol";
interface IAddAssetCheckGuard {
function isAddAssetCheckGuard() external view returns (bool);
function addAssetCheck(address poolLogic, IHasSupportedAsset.Asset calldata asset) external view;
}
"
},
"contracts/interfaces/guards/IAssetGuard.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
pragma experimental ABIEncoderV2;
interface IAssetGuard {
struct MultiTransaction {
address to;
bytes txData;
}
function withdrawProcessing(
address pool,
address asset,
uint256 withdrawPortion,
address to
) external returns (address, uint256, MultiTransaction[] memory transactions);
function getBalance(address pool, address asset) external view returns (uint256 balance);
function getDecimals(address asset) external view returns (uint256 decimals);
function removeAssetCheck(address poolLogic, address asset) external view;
}
"
},
"contracts/interfaces/guards/IGuard.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IGuard {
function txGuard(
address poolManagerLogic,
address to,
bytes calldata data
) external returns (uint16 txType, bool isPublic); // TODO: eventually update `txType` to be of enum type as per ITransactionTypes
}
"
},
"contracts/interfaces/IERC20Extended.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
interface IERC20Extended {
// ERC20 Optional Views
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
// Views
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function scaledBalanceOf(address user) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
// Mutative functions
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
// Events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
"
},
"contracts/interfaces/IGovernance.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IGovernance {
function contractGuards(address target) external view returns (address guard);
function assetGuards(uint16 assetType) external view returns (address guard);
}
"
},
"contracts/interfaces/IHasGuardInfo.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IHasGuardInfo {
// Get guard
function getContractGuard(address extContract) external view returns (address);
// Get asset guard
function getAssetGuard(address extContract) external view returns (address);
}
"
},
"contracts/interfaces/IHasSupportedAsset.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
pragma experimental ABIEncoderV2;
interface IHasSupportedAsset {
struct Asset {
address asset;
bool isDeposit;
}
function getSupportedAssets() external view returns (Asset[] memory);
function isSupportedAsset(address asset) external view returns (bool);
}
"
},
"contracts/interfaces/IPoolFactory.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
interface IPoolFactory {
function governanceAddress() external view returns (address);
function isPool(address pool) external view returns (bool);
function customCooldownWhitelist(address from) external view returns (bool);
function receiverWhitelist(address to) external view returns (bool);
function emitPoolEvent() external;
function emitPoolManagerEvent() external;
function isValidAsset(address asset) external view returns (bool);
function getAssetPrice(address asset) external view returns (uint256);
function getAssetHandler() external view returns (address);
}
"
},
"contracts/interfaces/IPoolLogic.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
pragma abicoder v2;
interface IPoolLogic {
struct ComplexAsset {
address supportedAsset;
bytes withdrawData; // at the moment could be only struct ComplexAssetSwapData
uint256 slippageTolerance; // duplicated from ComplexAssetSwapData on purpose
}
function factory() external view returns (address);
function poolManagerLogic() external view returns (address);
function setPoolManagerLogic(address _poolManagerLogic) external;
function calculateAvailableManagerFee(uint256 _fundValue) external view returns (uint256 fee);
function tokenPrice() external view returns (uint256 price);
function tokenPriceWithoutManagerFee() external view returns (uint256 price);
function mintManagerFee() external;
function deposit(address _asset, uint256 _amount) external returns (uint256 liquidityMinted);
function depositForWithCustomCooldown(
address _recipient,
address _asset,
uint256 _amount,
uint256 _cooldown
) external returns (uint256 liquidityMinted);
function withdraw(uint256 _fundTokenAmount) external;
function withdrawSafe(uint256 _fundTokenAmount, ComplexAsset[] memory _complexAssetsData) external;
function withdrawToSafe(
address _recipient,
uint256 _fundTokenAmount,
ComplexAsset[] memory _complexAssetsData
) external;
function setPoolPrivate(bool _privatePool) external;
function totalSupply() external view returns (uint256 supply);
function transfer(address to, uint256 value) external returns (bool);
function balanceOf(address owner) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function symbol() external view returns (string memory);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function getExitRemainingCooldown(address sender) external view returns (uint256 remaining);
}
"
},
"contracts/interfaces/IPoolManagerLogic.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IPoolManagerLogic {
function poolLogic() external view returns (address);
function isDepositAsset(address asset) external view returns (bool);
function validateAsset(address asset) external view returns (bool);
function assetValue(address asset) external view returns (uint256);
function assetValue(address asset, uint256 amount) external view returns (uint256);
function assetBalance(address asset) external view returns (uint256 balance);
function factory() external view returns (address);
function setPoolLogic(address fundAddress) external returns (bool);
function totalFundValue() external view returns (uint256);
function isMemberAllowed(address member) external view returns (bool);
function getFee() external view returns (uint256, uint256, uint256, uint256, uint256);
function minDepositUSD() external view returns (uint256);
function getEntryFeeInfo()
external
view
returns (uint256 entryFeeNumerator, uint256 poolFeeShareNumerator, uint256 feeDenominator);
function getExitFeeInfo()
external
view
returns (uint256 exitFeeNumerator, uint256 poolFeeShareNumerator, uint256 feeDenominator);
function maxSupplyCap() external view returns (uint256 supplyCap);
}
"
},
"contracts/interfaces/ITransactionTypes.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
/// @title Transaction types used in pool execTransaction() contract guards
/// @dev Gradually migrate to this enum as we update / add new contract guards
interface ITransactionTypes {
enum TransactionType {
NotUsed, // 0
Approve, // 1
Exchange, // 2
AddLiquidity, // 3
RemoveLiquidity, // 4
Stake, // 5
Unstake, // 6
Claim, // 7
UnstakeAndClaim, // 8
AaveDeposit, // 9
AaveWithdraw, // 10
AaveSetUserUseReserveAsCollateral, // 11
AaveBorrow, // 12
AaveRepay, // 13
AaveSwapBorrowRateMode, // 14
AaveRebalanceStableBorrowRate, // 15
BalancerJoinPool, // 16
BalancerExitPool, // 17
EasySwapperDeposit, // 18
EasySwapperWithdraw, // 19
UniswapV3Mint, // 20
UniswapV3IncreaseLiquidity, // 21
UniswapV3DecreaseLiquidity, // 22
UniswapV3Burn, // 23
UniswapV3Collect, // 24
UniswapV3Multicall, // 25
LyraOpenPosition, // 26
LyraClosePosition, // 27
LyraForceClosePosition, // 28
KwentaFuturesMarket, // 29
AddLiquiditySingle, // 30
RemoveLiquiditySingle, // 31
MaiTx, // 32
LyraAddCollateral, // 33
LyraLiquidatePosition, // 34
KwentaPerpsV2Market, // 35
RedeemSynth, // 36
SynthetixV3CreateAccount, // 37
SynthetixV3DepositCollateral, // 38
SynthetixV3WithdrawCollateral, // 39
SynthetixV3DelegateCollateral, // 40
SynthetixV3MintUSD, // 41
SynthetixV3BurnUSD, // 42
SynthetixV3Multicall, // 43
XRamCreateVest, // 44
XRamExitVest, // 45
SynthetixV3Wrap, // 46
SynthetixV3Unwrap, // 47
SynthetixV3BuySynth, // 48
SynthetixV3SellSynth, // 49
SonneMint, // 50
SonneRedeem, // 51
SonneRedeemUnderlying, // 52
SonneBorrow, // 53
SonneRepay, // 54
SonneComptrollerEnterMarkets, // 55
SonneComptrollerExitMarket, // 56
SynthetixV3UndelegateCollateral, // 57
AaveMigrateToV3, // 58
FlatMoneyStableDeposit, // 59
FlatMoneyStableWithdraw, // 60
FlatMoneyCancelOrder, // 61
SynthetixV3ClaimReward, // 62
VelodromeCLStake, // 63
VelodromeCLUnstake, // 64
VelodromeCLMint, // 65
VelodromeCLIncreaseLiquidity, // 66
VelodromeCLDecreaseLiquidity, // 67
VelodromeCLBurn, // 68
VelodromeCLCollect, // 69
VelodromeCLMulticall, // 70
FlatMoneyLeverageOpen, // 71
FlatMoneyLeverageAdjust, // 72
FlatMoneyLeverageClose, // 73
SynthetixV3PerpsCreateAccount, // 74
SynthetixV3PerpsModifyCollateral, // 75
SynthetixV3PerpsCommitOrder, // 76
CompoundDeposit, // 77
CompoundWithdraw, // 78
CompoundClaimRewards, // 79
RamsesCLMint, // 80
RamsesCLIncreaseLiquidity, // 81
RamsesCLDecreaseLiquidity, // 82
RamsesCLBurn, // 83
RamsesCLCollect, // 84
RamsesCLMulticall, // 85
RamsesCLGetReward, // 86
EasySwapperV2Deposit, // 87
EasySwapperV2InitWithdraw, // 88
EasySwapperV2CompleteWithdrawSingle, // 89
EasySwapperV2CompleteWithdrawMultiple, // 90
SafeTransferERC721, // 91
PancakeCLMint, // 92
PancakeCLIncreaseLiquidity, // 93
PancakeCLDecreaseLiquidity, // 94
PancakeCLBurn, // 95
PancakeCLCollect, // 96
PancakeCLMulticall, // 97
PancakeCLStake, // 98
PancakeCLUnstake, // 99
PancakeCLHarvest, // 100
GmxMulticall, // 101
GmxClaimFundingFees, // 102
GmxClaimCollateral, // 103
GmxCancelOrder, // 104
GmxCancelDeposit, // 105
GmxCancelWithdrawal, // 106
AcrossDepositV3, // 107
FluidLendingDeposit, // 108
FluidLendingWithdraw, // 109
BuyPendlePT, // 110
SellPendlePT, // 111
AaveSetEfficiencyMode // 112
}
}
"
},
"contracts/interfaces/pendle/IPMarket.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
// solhint-disable
pragma solidity 0.7.6;
interface IPMarket {
function readTokens() external view returns (address _SY, address _PT, address _YT);
function expiry() external view returns (uint256);
}
"
},
"contracts/interfaces/pendle/IPMarketFactoryV3.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.7.6;
interface IPMarketFactoryV3 {
function isValidMarket(address market) external view returns (bool);
}
"
},
"contracts/interfaces/pendle/IStandardizedYield.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.7.6;
interface IStandardizedYield {
/**
* @notice returns the address of the underlying yield token
*/
function yieldToken() external view returns (address);
}
"
},
"contracts/utils/TxDataUtils.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {BytesLib} from "@uniswap/v3-periphery/contracts/libraries/BytesLib.sol";
contract TxDataUtils {
using BytesLib for bytes;
function getMethod(bytes memory data) public pure returns (bytes4) {
return read4left(data, 0);
}
function getParams(bytes memory data) public pure returns (bytes memory) {
return data.slice(4, data.length - 4);
}
function getInput(bytes memory data, uint8 inputNum) public pure returns (bytes32) {
return read32(data, 32 * inputNum + 4, 32);
}
function getBytes(bytes memory data, uint8 inputNum, uint256 offset) public pure returns (bytes memory) {
require(offset < 20, "invalid offset"); // offset is in byte32 slots, not bytes
offset = offset * 32; // convert offset to bytes
uint256 bytesLenPos = uint256(read32(data, 32 * inputNum + 4 + offset, 32));
uint256 bytesLen = uint256(read32(data, bytesLenPos + 4 + offset, 32));
return data.slice(bytesLenPos + 4 + offset + 32, bytesLen);
}
function getArrayLast(bytes memory data, uint8 inputNum) public pure returns (bytes32) {
bytes32 arrayPos = read32(data, 32 * inputNum + 4, 32);
bytes32 arrayLen = read32(data, uint256(arrayPos) + 4, 32);
require(arrayLen > 0, "input is not array");
return read32(data, uint256(arrayPos) + 4 + (uint256(arrayLen) * 32), 32);
}
function getArrayLength(bytes memory data, uint8 inputNum) public pure returns (uint256) {
bytes32 arrayPos = read32(data, 32 * inputNum + 4, 32);
return uint256(read32(data, uint256(arrayPos) + 4, 32));
}
function getArrayIndex(bytes memory data, uint8 inputNum, uint8 arrayIndex) public pure returns (bytes32) {
bytes32 arrayPos = read32(data, 32 * inputNum + 4, 32);
bytes32 arrayLen = read32(data, uint256(arrayPos) + 4, 32);
require(arrayLen > 0, "input is not array");
require(uint256(arrayLen) > arrayIndex, "invalid array position");
return read32(data, uint256(arrayPos) + 4 + ((1 + uint256(arrayIndex)) * 32), 32);
}
function read4left(bytes memory data, uint256 offset) public pure returns (bytes4 o) {
require(data.length >= offset + 4, "Reading bytes out of bounds");
assembly {
o := mload(add(data, add(32, offset)))
}
}
function read32(bytes memory data, uint256 offset, uint256 length) public pure returns (bytes32 o) {
require(data.length >= offset + length, "Reading bytes out of bounds");
assembly {
o := mload(add(data, add(32, offset)))
let lb := sub(32, length)
if lb {
o := div(o, exp(2, mul(lb, 8)))
}
}
}
function convert32toAddress(bytes32 data) public pure returns (address o) {
return address(uint160(uint256(data)));
}
function sliceUint(bytes memory data, uint256 start) internal pure returns (uint256) {
require(data.length >= start + 32, "slicing out of range");
uint256 x;
assembly {
x := mload(add(data, add(0x20, start)))
}
return x;
}
}
"
}
},
"settings": {
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"optimizer": {
"enabled": true,
"runs": 20
}
}
}}
Submitted on: 2025-11-07 10:45:29
Comments
Log in to comment.
No comments yet.