diff --git a/contracts/payloads/IGP126/PayloadIGP126.sol b/contracts/payloads/IGP126/PayloadIGP126.sol new file mode 100644 index 00000000..d941bb88 --- /dev/null +++ b/contracts/payloads/IGP126/PayloadIGP126.sol @@ -0,0 +1,531 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.21; +pragma experimental ABIEncoderV2; + +import {BigMathMinified} from "../libraries/bigMathMinified.sol"; +import {LiquidityCalcs} from "../libraries/liquidityCalcs.sol"; +import {LiquiditySlotsLink} from "../libraries/liquiditySlotsLink.sol"; + +import {IGovernorBravo} from "../common/interfaces/IGovernorBravo.sol"; +import {ITimelock} from "../common/interfaces/ITimelock.sol"; + +import { + IFluidLiquidityAdmin, + AdminModuleStructs as FluidLiquidityAdminStructs +} from "../common/interfaces/IFluidLiquidity.sol"; +import { + IFluidReserveContract +} from "../common/interfaces/IFluidReserveContract.sol"; + +import {IFluidVaultFactory} from "../common/interfaces/IFluidVaultFactory.sol"; +import {IFluidDexFactory} from "../common/interfaces/IFluidDexFactory.sol"; + +import { + IFluidDex, + IFluidAdminDex, + IFluidDexResolver +} from "../common/interfaces/IFluidDex.sol"; + +import {IFluidVault, IFluidVaultT1} from "../common/interfaces/IFluidVault.sol"; + +import {IFTokenAdmin, ILendingRewards} from "../common/interfaces/IFToken.sol"; + +import {ICodeReader} from "../common/interfaces/ICodeReader.sol"; +import {IDSAV2} from "../common/interfaces/IDSA.sol"; +import {IERC20} from "../common/interfaces/IERC20.sol"; +import {IInfiniteProxy} from "../common/interfaces/IInfiniteProxy.sol"; +import {PayloadIGPConstants} from "../common/constants.sol"; +import {PayloadIGPHelpers} from "../common/helpers.sol"; +import {PayloadIGPMain} from "../common/main.sol"; + +interface IFluidLiquidityRollback { + function registerRollbackImplementation( + address oldImplementation_, + address newImplementation_ + ) external; + + function registerRollbackDummyImplementation() external; +} + +interface IOwnable { + function transferOwnership(address newOwner) external; +} + +/// @notice IGP126: Add TEAM_MULTISIG as auth on wstUSR vaults/DEXes, register & upgrade UserModule LL via RollbackModule, +/// set LL auth for operateOnBehalfOf, set new VaultFactory owner, max-restrict borrows, pause wstUSR DEX swapAndArbitrage. +contract PayloadIGP126 is PayloadIGPMain { + uint256 public constant PROPOSAL_ID = 126; + + address public constant OLD_USER_MODULE = + 0x2e4015880367b7C2613Df77f816739D97A8C46aD; + + /// @dev IFluidLiquidityLogic.operateOnBehalfOf(address,address,int256,int256,bytes) + bytes4 private constant OPERATE_ON_BEHALF_OF_SIG = + bytes4( + keccak256("operateOnBehalfOf(address,address,int256,int256,bytes)") + ); + + // --- Configurable addresses (Team Multisig can set before execution) --- + address public userModuleAddress = address(0); + address public dummyImplementationAddress = address(0); + address public onBehalfOfAuth = address(0); + address public vaultFactoryOwner = address(0); + address public pauseableAuth = address(0); + address public pausableDexAuth = address(0); + + // --- Lock flags (once true, the corresponding address can no longer be changed) --- + bool public userModuleAddressLocked; + bool public dummyImplementationAddressLocked; + bool public onBehalfOfAuthLocked; + bool public vaultFactoryOwnerLocked; + bool public pauseableAuthLocked; + bool public pausableDexAuthLocked; + + function lockUserModuleAddress() external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + userModuleAddressLocked = true; + } + + function lockDummyImplementationAddress() external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + dummyImplementationAddressLocked = true; + } + + function lockOnBehalfOfAuth() external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + onBehalfOfAuthLocked = true; + } + + function lockVaultFactoryOwner() external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + vaultFactoryOwnerLocked = true; + } + + function lockPauseableAuth() external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + pauseableAuthLocked = true; + } + + function lockPausableDexAuth() external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + pausableDexAuthLocked = true; + } + + function setUserModuleAddress(address userModuleAddress_) external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + require(!userModuleAddressLocked, "locked"); + userModuleAddress = userModuleAddress_; + } + + function setDummyImplementationAddress( + address dummyImplementationAddress_ + ) external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + require(!dummyImplementationAddressLocked, "locked"); + dummyImplementationAddress = dummyImplementationAddress_; + } + + function setOnBehalfOfAuth(address onBehalfOfAuth_) external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + require(!onBehalfOfAuthLocked, "locked"); + onBehalfOfAuth = onBehalfOfAuth_; + } + + function setVaultFactoryOwner(address vaultFactoryOwner_) external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + require(!vaultFactoryOwnerLocked, "locked"); + vaultFactoryOwner = vaultFactoryOwner_; + } + + function setPauseableAuth(address pauseableAuth_) external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + require(!pauseableAuthLocked, "locked"); + pauseableAuth = pauseableAuth_; + } + + function setPausableDexAuth(address pausableDexAuth_) external { + require(msg.sender == TEAM_MULTISIG, "not-team-multisig"); + require(!pausableDexAuthLocked, "locked"); + pausableDexAuth = pausableDexAuth_; + } + + function execute() public virtual override { + super.execute(); + + // Action 1: Add TEAM_MULTISIG as auth on all wstUSR vaults and DEXes + action1(); + + // Action 2: Register UserModule LL upgrade on RollbackModule + action2(); + + // Action 3: Update UserModule LL to settable address + action3(); + + // Action 4: Register DummyImplementation rollback on RollbackModule + action4(); + + // Action 5: Update DummyImplementation on LL to settable address + action5(); + + // Action 6: Set a contract as auth on LL (for operateOnBehalfOf) + action6(); + + // Action 7: Set new owner of VaultFactory (for position transfer wrapper) + action7(); + + // Action 8: Set max restricted borrow limits on all wstUSR vaults + action8(); + + // Action 9: Pause swapAndArbitrage on all wstUSR-related DEXes + action9(); + + // Action 10: Set pauseableAuth as auth on LL + action10(); + + // Action 11: Set pausableDexAuth as globalAuth on DexFactory + action11(); + + } + + function verifyProposal() public view override {} + + function _PROPOSAL_ID() internal view override returns (uint256) { + return PROPOSAL_ID; + } + + /** + * | + * | Proposal Payload Actions | + * |__________________________________ + */ + + /// @notice Action 1: Add TEAM_MULTISIG as auth on all wstUSR vaults and DEXes + function action1() internal isActionSkippable(1) { + // wstUSR Vaults + VAULT_FACTORY.setVaultAuth(getVaultAddress(110), TEAM_MULTISIG, true); // wstUSR / USDC + VAULT_FACTORY.setVaultAuth(getVaultAddress(111), TEAM_MULTISIG, true); // wstUSR / USDT + VAULT_FACTORY.setVaultAuth(getVaultAddress(112), TEAM_MULTISIG, true); // wstUSR / GHO + // skip 113 wstUSR-USDT / USDT: already max restricted / deprecated + VAULT_FACTORY.setVaultAuth(getVaultAddress(133), TEAM_MULTISIG, true); // wstUSR-USDC <> USDC + VAULT_FACTORY.setVaultAuth(getVaultAddress(134), TEAM_MULTISIG, true); // wstUSR-USDC <> USDC-USDT + VAULT_FACTORY.setVaultAuth(getVaultAddress(135), TEAM_MULTISIG, true); // wstUSR-USDC <> USDC-USDT concentrated + // skip 142 wstUSR / USDtb: already max restricted / deprecated + VAULT_FACTORY.setVaultAuth(getVaultAddress(143), TEAM_MULTISIG, true); // wstUSR <> USDC-USDT + VAULT_FACTORY.setVaultAuth(getVaultAddress(144), TEAM_MULTISIG, true); // wstUSR <> USDC-USDT concentrated + + // wstUSR DEXes + DEX_FACTORY.setDexAuth(getDexAddress(27), TEAM_MULTISIG, true); // wstUSR-USDC + // skip 29 wstUSR-USDT: already max restricted / deprecated + } + + /// @notice Action 2: Register UserModule LL upgrade on RollbackModule (must happen before the actual upgrade) + function action2() internal isActionSkippable(2) { + address newUserModule_ = PayloadIGP126(ADDRESS_THIS) + .userModuleAddress(); + require(newUserModule_ != address(0), "user-module-not-set"); + + IFluidLiquidityRollback(address(LIQUIDITY)) + .registerRollbackImplementation(OLD_USER_MODULE, newUserModule_); + } + + /// @notice Action 3: Update UserModule LL to settable address + function action3() internal isActionSkippable(3) { + address newUserModule_ = PayloadIGP126(ADDRESS_THIS) + .userModuleAddress(); + require(newUserModule_ != address(0), "user-module-not-set"); + + bytes4[] memory baseSigs_ = IInfiniteProxy(address(LIQUIDITY)) + .getImplementationSigs(OLD_USER_MODULE); + uint256 len = baseSigs_.length; + bytes4[] memory sigs_ = new bytes4[](len + 1); + for (uint256 i; i < len; ++i) { + sigs_[i] = baseSigs_[i]; + } + sigs_[len] = OPERATE_ON_BEHALF_OF_SIG; + + IInfiniteProxy(address(LIQUIDITY)).removeImplementation( + OLD_USER_MODULE + ); + + IInfiniteProxy(address(LIQUIDITY)).addImplementation( + newUserModule_, + sigs_ + ); + } + + /// @notice Action 4: Register DummyImplementation rollback on RollbackModule (must happen before the actual update) + function action4() internal isActionSkippable(4) { + IFluidLiquidityRollback(address(LIQUIDITY)) + .registerRollbackDummyImplementation(); + } + + /// @notice Action 5: Update DummyImplementation on LL to settable address + function action5() internal isActionSkippable(5) { + address newDummyImpl_ = PayloadIGP126(ADDRESS_THIS) + .dummyImplementationAddress(); + require(newDummyImpl_ != address(0), "dummy-impl-not-set"); + + IInfiniteProxy(address(LIQUIDITY)).setDummyImplementation( + newDummyImpl_ + ); + } + + /// @notice Action 6: Set a contract as auth on LL (for operateOnBehalfOf) + function action6() internal isActionSkippable(6) { + address authAddress_ = PayloadIGP126(ADDRESS_THIS).onBehalfOfAuth(); + require(authAddress_ != address(0), "on-behalf-of-auth-not-set"); + + FluidLiquidityAdminStructs.AddressBool[] + memory authsStatus_ = new FluidLiquidityAdminStructs.AddressBool[]( + 1 + ); + authsStatus_[0] = FluidLiquidityAdminStructs.AddressBool({ + addr: authAddress_, + value: true + }); + LIQUIDITY.updateAuths(authsStatus_); + } + + /// @notice Action 7: Set new owner of VaultFactory (for position transfer wrapper) + function action7() internal isActionSkippable(7) { + address newOwner_ = PayloadIGP126(ADDRESS_THIS).vaultFactoryOwner(); + require(newOwner_ != address(0), "vault-factory-owner-not-set"); + + IOwnable(address(VAULT_FACTORY)).transferOwnership(newOwner_); + } + + /// @notice Action 8: Set max restricted borrow limits on all wstUSR vaults + function action8() internal isActionSkippable(8) { + // --- Borrow limits at Liquidity Layer (T1 and T2 vaults) --- + + // Vault 110: wstUSR / USDC (T1) + setBorrowProtocolLimitsPaused(getVaultAddress(110), USDC_ADDRESS); + + // Vault 111: wstUSR / USDT (T1) + setBorrowProtocolLimitsPaused(getVaultAddress(111), USDT_ADDRESS); + + // Vault 112: wstUSR / GHO (T1) + setBorrowProtocolLimitsPaused(getVaultAddress(112), GHO_ADDRESS); + + // skip 113 wstUSR-USDT / USDT: already max restricted / deprecated + + // Vault 133: wstUSR-USDC <> USDC (T2) + setBorrowProtocolLimitsPaused(getVaultAddress(133), USDC_ADDRESS); + + // skip 142 wstUSR / USDtb: already max restricted / deprecated + + // --- Borrow limits at DEX level (T3 and T4 vaults) --- + + address USDC_USDT_DEX = getDexAddress(2); + address USDC_USDT_CONCENTRATED_DEX = getDexAddress(34); + + // Vault 134: wstUSR-USDC <> USDC-USDT (T4) — borrows from USDC-USDT DEX + setBorrowProtocolLimitsPausedDex(USDC_USDT_DEX, getVaultAddress(134)); + + // skip 135 wstUSR-USDC / USDC-USDT concentrated: already max restricted / deprecated + + // Vault 143: wstUSR <> USDC-USDT (T3) — borrows from USDC-USDT DEX + setBorrowProtocolLimitsPausedDex(USDC_USDT_DEX, getVaultAddress(143)); + + // Vault 144: wstUSR <> USDC-USDT concentrated (T3) — borrows from USDC-USDT concentrated DEX + setBorrowProtocolLimitsPausedDex( + USDC_USDT_CONCENTRATED_DEX, + getVaultAddress(144) + ); + } + + /// @notice Action 9: Pause `swapAndArbitrage` on all wstUSR-related DEXes + function action9() internal isActionSkippable(9) { + IFluidDex(getDexAddress(27)).pauseSwapAndArbitrage(); // wstUSR-USDC + // skip 29 wstUSR-USDT: already max restricted / deprecated + } + + /// @notice Action 10: Set pauseableAuth as auth on Liquidity Layer + function action10() internal isActionSkippable(10) { + address authAddress_ = PayloadIGP126(ADDRESS_THIS).pauseableAuth(); + require(authAddress_ != address(0), "pauseable-auth-not-set"); + + FluidLiquidityAdminStructs.AddressBool[] + memory authsStatus_ = new FluidLiquidityAdminStructs.AddressBool[]( + 1 + ); + authsStatus_[0] = FluidLiquidityAdminStructs.AddressBool({ + addr: authAddress_, + value: true + }); + LIQUIDITY.updateAuths(authsStatus_); + } + + /// @notice Action 11: Set pausableDexAuth as globalAuth on DexFactory + function action11() internal isActionSkippable(11) { + address authAddress_ = PayloadIGP126(ADDRESS_THIS).pausableDexAuth(); + require(authAddress_ != address(0), "pausable-dex-auth-not-set"); + + DEX_FACTORY.setGlobalAuth(authAddress_, true); + } + + /** + * | + * | Payload Actions End Here | + * |__________________________________ + */ + + // Token Prices Constants + uint256 public constant ETH_USD_PRICE = 2_000 * 1e2; + uint256 public constant wstETH_USD_PRICE = 3_575 * 1e2; + uint256 public constant weETH_USD_PRICE = 3_050 * 1e2; + uint256 public constant rsETH_USD_PRICE = 2_980 * 1e2; + uint256 public constant weETHs_USD_PRICE = 2_920 * 1e2; + uint256 public constant mETH_USD_PRICE = 3_040 * 1e2; + uint256 public constant ezETH_USD_PRICE = 3_000 * 1e2; + uint256 public constant OSETH_USD_PRICE = 3_060 * 1e2; + + uint256 public constant BTC_USD_PRICE = 69_000 * 1e2; + + uint256 public constant STABLE_USD_PRICE = 1 * 1e2; + uint256 public constant sUSDe_USD_PRICE = 1.20 * 1e2; + uint256 public constant sUSDs_USD_PRICE = 1.08 * 1e2; + uint256 public constant syrupUSDT_USD_PRICE = 1.10 * 1e2; + uint256 public constant syrupUSDC_USD_PRICE = 1.14 * 1e2; + uint256 public constant REUSD_USD_PRICE = 1.06 * 1e2; + uint256 public constant csUSDL_USD_PRICE = 1.03 * 1e2; + + uint256 public constant FLUID_USD_PRICE = 2.19 * 1e2; + + uint256 public constant RLP_USD_PRICE = 1.26 * 1e2; + uint256 public constant wstUSR_USD_PRICE = 1.12 * 1e2; + uint256 public constant XAUT_USD_PRICE = 4_040 * 1e2; + uint256 public constant PAXG_USD_PRICE = 4_050 * 1e2; + uint256 public constant JRUSDE_USD_PRICE = 1.00 * 1e2; + uint256 public constant SRUSDE_USD_PRICE = 1.00 * 1e2; + + function getRawAmount( + address token, + uint256 amount, + uint256 amountInUSD, + bool isSupply + ) public view override returns (uint256) { + if (amount > 0 && amountInUSD > 0) { + revert("both usd and amount are not zero"); + } + uint256 exchangePriceAndConfig_ = LIQUIDITY.readFromStorage( + LiquiditySlotsLink.calculateMappingStorageSlot( + LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT, + token + ) + ); + + ( + uint256 supplyExchangePrice, + uint256 borrowExchangePrice + ) = LiquidityCalcs.calcExchangePrices(exchangePriceAndConfig_); + + uint256 usdPrice = 0; + uint256 decimals = 18; + if (token == ETH_ADDRESS) { + usdPrice = ETH_USD_PRICE; + decimals = 18; + } else if (token == wstETH_ADDRESS) { + usdPrice = wstETH_USD_PRICE; + decimals = 18; + } else if (token == weETH_ADDRESS) { + usdPrice = weETH_USD_PRICE; + decimals = 18; + } else if (token == rsETH_ADDRESS) { + usdPrice = rsETH_USD_PRICE; + decimals = 18; + } else if (token == weETHs_ADDRESS) { + usdPrice = weETHs_USD_PRICE; + decimals = 18; + } else if (token == mETH_ADDRESS) { + usdPrice = mETH_USD_PRICE; + decimals = 18; + } else if (token == ezETH_ADDRESS) { + usdPrice = ezETH_USD_PRICE; + decimals = 18; + } else if (token == OSETH_ADDRESS) { + usdPrice = OSETH_USD_PRICE; + decimals = 18; + } else if ( + token == cbBTC_ADDRESS || + token == WBTC_ADDRESS || + token == eBTC_ADDRESS || + token == lBTC_ADDRESS + ) { + usdPrice = BTC_USD_PRICE; + decimals = 8; + } else if (token == tBTC_ADDRESS) { + usdPrice = BTC_USD_PRICE; + decimals = 18; + } else if (token == USDC_ADDRESS || token == USDT_ADDRESS) { + usdPrice = STABLE_USD_PRICE; + decimals = 6; + } else if (token == sUSDe_ADDRESS) { + usdPrice = sUSDe_USD_PRICE; + decimals = 18; + } else if (token == sUSDs_ADDRESS) { + usdPrice = sUSDs_USD_PRICE; + decimals = 18; + } else if (token == syrupUSDT_ADDRESS) { + usdPrice = syrupUSDT_USD_PRICE; + decimals = 6; + } else if (token == syrupUSDC_ADDRESS) { + usdPrice = syrupUSDC_USD_PRICE; + decimals = 6; + } else if (token == REUSD_ADDRESS) { + usdPrice = REUSD_USD_PRICE; + decimals = 18; + } else if (token == csUSDL_ADDRESS) { + usdPrice = csUSDL_USD_PRICE; + decimals = 18; + } else if (token == JRUSDE_ADDRESS) { + usdPrice = JRUSDE_USD_PRICE; + decimals = 18; + } else if (token == SRUSDE_ADDRESS) { + usdPrice = SRUSDE_USD_PRICE; + decimals = 18; + } else if ( + token == GHO_ADDRESS || + token == USDe_ADDRESS || + token == deUSD_ADDRESS || + token == USR_ADDRESS || + token == USD0_ADDRESS || + token == fxUSD_ADDRESS || + token == BOLD_ADDRESS || + token == iUSD_ADDRESS || + token == USDTb_ADDRESS + ) { + usdPrice = STABLE_USD_PRICE; + decimals = 18; + } else if (token == INST_ADDRESS) { + usdPrice = FLUID_USD_PRICE; + decimals = 18; + } else if (token == wstUSR_ADDRESS) { + usdPrice = wstUSR_USD_PRICE; + decimals = 18; + } else if (token == RLP_ADDRESS) { + usdPrice = RLP_USD_PRICE; + decimals = 18; + } else if (token == XAUT_ADDRESS) { + usdPrice = XAUT_USD_PRICE; + decimals = 6; + } else if (token == PAXG_ADDRESS) { + usdPrice = PAXG_USD_PRICE; + decimals = 18; + } else { + revert("not-found"); + } + + uint256 exchangePrice = isSupply + ? supplyExchangePrice + : borrowExchangePrice; + + if (amount > 0) { + return (amount * 1e12) / exchangePrice; + } else { + return + (amountInUSD * 1e12 * (10 ** decimals)) / + ((usdPrice * exchangePrice) / 1e2); + } + } +} diff --git a/contracts/payloads/IGP126/description.md b/contracts/payloads/IGP126/description.md new file mode 100644 index 00000000..476c78e7 --- /dev/null +++ b/contracts/payloads/IGP126/description.md @@ -0,0 +1,137 @@ +# wstUSR Migration Prep, Liquidity Layer Upgrades, Pauseable Auth, and VaultFactory Ownership Transfer + +## Summary + +This proposal implements protocol updates across four areas: (1) adds Team Multisig authorization on active wstUSR vaults and DEXes, max-restricts their borrow limits, and pauses swapAndArbitrage to prepare for wstUSR migration, (2) upgrades the Liquidity Layer UserModule and DummyImplementation via the RollbackModule with rollback safety registrations, and adds a new LL auth for `operateOnBehalfOf`, (3) registers pauseable auth contracts on the Liquidity Layer and DexFactory for emergency pause capabilities, and (4) transfers VaultFactory ownership to enable a position transfer wrapper. + +All implementation addresses (`userModuleAddress`, `dummyImplementationAddress`, `onBehalfOfAuth`, `vaultFactoryOwner`, `pauseableAuth`, `pausableDexAuth`) are configurable by Team Multisig before governance execution. + +## Code Changes + +### Action 1: Add Team Multisig as Auth on wstUSR Vaults and DEXes + +Adds Team Multisig as authorized on all active wstUSR-related vaults and DEXes to enable emergency operations during the migration period. + +**Vaults** (via `setVaultAuth`): +- Vault 110 — wstUSR / USDC (T1) +- Vault 111 — wstUSR / USDT (T1) +- Vault 112 — wstUSR / GHO (T1) +- Vault 133 — wstUSR-USDC <> USDC (T2) +- Vault 134 — wstUSR-USDC <> USDC-USDT (T4) +- Vault 135 — wstUSR-USDC <> USDC-USDT concentrated (T3) +- Vault 143 — wstUSR <> USDC-USDT (T3) +- Vault 144 — wstUSR <> USDC-USDT concentrated (T3) + +**DEXes** (via `setDexAuth`): +- DEX Pool 27 — wstUSR-USDC + +> Skipped: Vault 113, Vault 142, DEX 29 — already max-restricted / deprecated in IGP-123. + +### Action 2: Register UserModule Upgrade on RollbackModule + +- Calls `registerRollbackImplementation(OLD_USER_MODULE, userModuleAddress)` on the Liquidity Layer +- Captures the current UserModule (`0x2e4015880367b7C2613Df77f816739D97A8C46aD`) for rollback safety before the upgrade +- Requires `userModuleAddress` to be set by Team Multisig before execution + +### Action 3: Upgrade UserModule on Liquidity Layer + +- Removes the old UserModule (`0x2e4015880367b7C2613Df77f816739D97A8C46aD`) from the InfiniteProxy +- Adds the new `userModuleAddress` with all existing function selectors **plus** the new `operateOnBehalfOf(address,address,int256,int256,bytes)` selector +- Requires `userModuleAddress` to be set by Team Multisig before execution + +### Action 4: Register DummyImplementation Rollback on RollbackModule + +- Calls `registerRollbackDummyImplementation()` on the Liquidity Layer +- Captures the current DummyImplementation for rollback safety before the update + +### Action 5: Update DummyImplementation on Liquidity Layer + +- Calls `setDummyImplementation(dummyImplementationAddress)` on the InfiniteProxy +- Requires `dummyImplementationAddress` to be set by Team Multisig before execution + +### Action 6: Add Liquidity Layer Auth for operateOnBehalfOf + +- Calls `LIQUIDITY.updateAuths()` to add `onBehalfOfAuth` as an authorized address on the Liquidity Layer +- Enables the authorized contract to call `operateOnBehalfOf` on behalf of users +- Requires `onBehalfOfAuth` to be set by Team Multisig before execution + +### Action 7: Transfer VaultFactory Ownership + +- Calls `transferOwnership(vaultFactoryOwner)` on the VaultFactory +- Enables the new owner contract to manage vault position transfers +- Requires `vaultFactoryOwner` to be set by Team Multisig before execution + +### Action 8: Max-Restrict Borrow Limits on wstUSR Vaults + +Applies max-restriction borrow protocol limits (0.01% expand, max duration, minimal ceilings) to effectively cap new borrows at near-zero without pausing the vaults. + +**At Liquidity Layer** (via `setBorrowProtocolLimitsPaused`): +- Vault 110 — wstUSR / USDC → restricts USDC borrowing +- Vault 111 — wstUSR / USDT → restricts USDT borrowing +- Vault 112 — wstUSR / GHO → restricts GHO borrowing +- Vault 133 — wstUSR-USDC <> USDC → restricts USDC borrowing + +**At DEX Level** (via `setBorrowProtocolLimitsPausedDex`): +- Vault 134 — borrows from USDC-USDT DEX (Pool 2) +- Vault 143 — borrows from USDC-USDT DEX (Pool 2) +- Vault 144 — borrows from USDC-USDT concentrated DEX (Pool 34) + +> Skipped: Vault 113, Vault 135, Vault 142 — already max-restricted / deprecated in IGP-123. + +### Action 9: Pause swapAndArbitrage on wstUSR DEXes + +- Calls `pauseSwapAndArbitrage()` on DEX Pool 27 (wstUSR-USDC) + +> Skipped: DEX Pool 29 (wstUSR-USDT) — already max-restricted / deprecated in IGP-123. + +### Action 10: Set Pauseable Auth on Liquidity Layer + +- Calls `LIQUIDITY.updateAuths()` to add `pauseableAuth` as an authorized address on the Liquidity Layer +- Enables the pauseable contract to execute emergency pauses on LL protocols +- Requires `pauseableAuth` to be set by Team Multisig before execution + +### Action 11: Set Pausable DEX Auth as Global Auth on DexFactory + +- Calls `DEX_FACTORY.setGlobalAuth(pausableDexAuth, true)` to grant global auth on DexFactory +- Enables the pausable contract to execute emergency pauses on DEX protocols +- Requires `pausableDexAuth` to be set by Team Multisig before execution + +## Description + +This proposal covers four areas of protocol maintenance and infrastructure upgrades: + +1. **wstUSR Migration Preparation** + - Adds Team Multisig as authorized on 8 active wstUSR vaults (110, 111, 112, 133, 134, 135, 143, 144) and DEX Pool 27 to enable emergency operations during the migration period + - Max-restricts borrow limits on all active wstUSR vaults (110, 111, 112, 133 at LL; 134, 143, 144 at DEX level) to prevent new borrowing while allowing existing users to manage and exit positions + - Pauses `swapAndArbitrage` on the wstUSR-USDC DEX (Pool 27) to halt trading activity + - Vaults 113, 142, 135 and DEX 29 are excluded as they were already deprecated and max-restricted in IGP-123 + +2. **Liquidity Layer Upgrades via RollbackModule** + - Upgrades the UserModule on the Liquidity Layer's InfiniteProxy to a new implementation that adds support for `operateOnBehalfOf`. Both the old UserModule and the old DummyImplementation are registered on the RollbackModule before replacement, enabling rollback within the safety period if issues are discovered + - Updates the DummyImplementation on the InfiniteProxy to a new version + - Adds a new authorized address (`onBehalfOfAuth`) on the Liquidity Layer to enable delegated operations via `operateOnBehalfOf` + - All upgrade addresses are configurable by Team Multisig before governance execution for operational flexibility + +3. **Pauseable Auth Registration** + - Registers `pauseableAuth` as an authorized address on the Liquidity Layer and `pausableDexAuth` as a global auth on DexFactory + - Enables dedicated pause contracts to execute emergency pauses on both LL and DEX protocols without requiring a full governance proposal + - Both addresses are configurable by Team Multisig before governance execution + +4. **VaultFactory Ownership Transfer** + - Transfers VaultFactory ownership to a new contract (`vaultFactoryOwner`) to enable a position transfer wrapper that allows users to transfer vault positions + - The new owner address is configurable by Team Multisig before governance execution + +### Configurable Addresses (Team Multisig sets before execution) + +| Variable | Purpose | +|---|---| +| `userModuleAddress` | New UserModule implementation for Liquidity Layer | +| `dummyImplementationAddress` | New DummyImplementation for Liquidity Layer InfiniteProxy | +| `onBehalfOfAuth` | Contract authorized for `operateOnBehalfOf` on Liquidity Layer | +| `vaultFactoryOwner` | New owner of VaultFactory (position transfer wrapper) | +| `pauseableAuth` | Contract authorized for emergency pauses on Liquidity Layer | +| `pausableDexAuth` | Contract authorized as global auth on DexFactory for emergency pauses | + +## Conclusion + +IGP-126 prepares the wstUSR ecosystem for migration by adding Team Multisig authorization and max-restricting borrow limits across active vaults, upgrades the Liquidity Layer with a new UserModule (adding `operateOnBehalfOf` support) and DummyImplementation via the RollbackModule for safe rollback capability, registers pauseable auth contracts on both the Liquidity Layer and DexFactory for emergency response, and transfers VaultFactory ownership to enable position transfers. Existing users in wstUSR markets can still manage and exit their positions. diff --git a/contracts/payloads/IGP126/simulation/MockChainlinkFeed.sol b/contracts/payloads/IGP126/simulation/MockChainlinkFeed.sol new file mode 100644 index 00000000..0912c757 --- /dev/null +++ b/contracts/payloads/IGP126/simulation/MockChainlinkFeed.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * Mock Chainlink aggregator for simulation: latestRoundData() returns fixed values. + * Used via tenderly_setCode in setup.ts so FluidGenericOracle._readChainlinkSource(feed) gets these values. + */ +contract MockChainlinkFeed { + function latestRoundData() + external + pure + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) + { + return (1, 106475560, 1771926611, 1771926611, 1); + } +} diff --git a/contracts/payloads/IGP126/simulation/setup.ts b/contracts/payloads/IGP126/simulation/setup.ts new file mode 100644 index 00000000..8e448128 --- /dev/null +++ b/contracts/payloads/IGP126/simulation/setup.ts @@ -0,0 +1,154 @@ +/** + * Pre-Setup Script for IGP126 Payload Simulation + * + * 1. Mock Chainlink feed 0x66ac... so latestRoundData() returns fixed values (for FluidGenericOracle._readChainlinkSource / OSETH oracle) + * 2. Set configurable addresses on the payload (userModuleAddress, dummyImplementationAddress, onBehalfOfAuth, vaultFactoryOwner, pauseableAuth, pausableDexAuth) + */ + +import { JsonRpcProvider, ethers } from "ethers"; +import * as fs from "fs"; +import * as path from "path"; + +const TEAM_MULTISIG = "0x4F6F977aCDD1177DCD81aB83074855EcB9C2D49e"; + +/** Chainlink feed mocked so latestRoundData() returns (1, 106475560, 1771926611, 1771926611, 1) */ +const CHAINLINK_FEED_TO_MOCK = "0x66ac817f997efd114edfcccdce99f3268557b32c"; + +/** Dummy addresses for simulation (non-zero so require checks pass) */ +const DUMMY_USER_MODULE = "0x0000000000000000000000000000000000000001"; +const DUMMY_DUMMY_IMPLEMENTATION = + "0x0000000000000000000000000000000000000004"; +const DUMMY_ON_BEHALF_OF_AUTH = "0x0000000000000000000000000000000000000002"; +const DUMMY_VAULT_FACTORY_OWNER = "0x0000000000000000000000000000000000000003"; +const DUMMY_PAUSEABLE_AUTH = "0x0000000000000000000000000000000000000005"; +const DUMMY_PAUSABLE_DEX_AUTH = "0x0000000000000000000000000000000000000006"; + +async function mockChainlinkFeed(provider: JsonRpcProvider): Promise { + const artifactPath = path.join( + process.cwd(), + "artifacts", + "contracts", + "payloads", + "IGP126", + "simulation", + "MockChainlinkFeed.sol", + "MockChainlinkFeed.json", + ); + if (!fs.existsSync(artifactPath)) { + throw new Error( + `MockChainlinkFeed artifact not found at ${artifactPath}. Run 'npm run compile' first.`, + ); + } + const artifact = JSON.parse(fs.readFileSync(artifactPath, "utf-8")); + const raw = + artifact.deployedBytecode?.object ?? artifact.deployedBytecode ?? ""; + const bytecode = + typeof raw === "string" && raw.length > 0 + ? raw.startsWith("0x") + ? raw + : "0x" + raw + : ""; + if (!bytecode) { + throw new Error( + "MockChainlinkFeed artifact has no deployedBytecode.object", + ); + } + await provider.send("tenderly_setCode", [CHAINLINK_FEED_TO_MOCK, bytecode]); +} + +async function setConfigurableAddresses( + provider: JsonRpcProvider, + payloadAddress: string, +): Promise { + const iface = new ethers.Interface([ + "function setUserModuleAddress(address) external", + "function setDummyImplementationAddress(address) external", + "function setOnBehalfOfAuth(address) external", + "function setVaultFactoryOwner(address) external", + "function setPauseableAuth(address) external", + "function setPausableDexAuth(address) external", + ]); + + const calls: { name: string; data: string }[] = [ + { + name: "setUserModuleAddress", + data: iface.encodeFunctionData("setUserModuleAddress", [ + DUMMY_USER_MODULE, + ]), + }, + { + name: "setDummyImplementationAddress", + data: iface.encodeFunctionData("setDummyImplementationAddress", [ + DUMMY_DUMMY_IMPLEMENTATION, + ]), + }, + { + name: "setOnBehalfOfAuth", + data: iface.encodeFunctionData("setOnBehalfOfAuth", [ + DUMMY_ON_BEHALF_OF_AUTH, + ]), + }, + { + name: "setVaultFactoryOwner", + data: iface.encodeFunctionData("setVaultFactoryOwner", [ + DUMMY_VAULT_FACTORY_OWNER, + ]), + }, + { + name: "setPauseableAuth", + data: iface.encodeFunctionData("setPauseableAuth", [ + DUMMY_PAUSEABLE_AUTH, + ]), + }, + { + name: "setPausableDexAuth", + data: iface.encodeFunctionData("setPausableDexAuth", [ + DUMMY_PAUSABLE_DEX_AUTH, + ]), + }, + ]; + + for (const call of calls) { + const txHash = await provider.send("eth_sendTransaction", [ + { + from: TEAM_MULTISIG, + to: payloadAddress, + data: call.data, + value: "0x0", + gas: "0x989680", + gasPrice: "0x0", + }, + ]); + const receipt = await provider.waitForTransaction(txHash); + if (!receipt || receipt.status !== 1) { + throw new Error(`${call.name} transaction failed`); + } + console.log(`[SETUP] ${call.name} set successfully`); + } +} + +export async function preSetup( + provider: JsonRpcProvider, + payloadAddress?: string, +): Promise { + console.log("[SETUP] Running pre-setup for IGP126..."); + + try { + await mockChainlinkFeed(provider); + + if (payloadAddress) { + await setConfigurableAddresses(provider, payloadAddress); + } else { + console.warn( + "[SETUP] No payload address provided, skipping configurable address setup", + ); + } + + console.log("[SETUP] Pre-setup completed successfully"); + } catch (error: any) { + console.error("[SETUP] Pre-setup failed:", error.message); + throw error; + } +} + +export default preSetup; diff --git a/ignition/deployments/chain-1/artifacts/PayloadModule#PayloadIGP126.json b/ignition/deployments/chain-1/artifacts/PayloadModule#PayloadIGP126.json new file mode 100644 index 00000000..6ec1a8bb --- /dev/null +++ b/ignition/deployments/chain-1/artifacts/PayloadModule#PayloadIGP126.json @@ -0,0 +1,1211 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "PayloadIGP126", + "sourceName": "contracts/payloads/IGP126/PayloadIGP126.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorId_", + "type": "uint256" + } + ], + "name": "FluidLiquidityCalcsError", + "type": "error" + }, + { + "inputs": [], + "name": "ADDRESS_THIS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BTC_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEX_FACTORY", + "outputs": [ + { + "internalType": "contract IFluidDexFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DSA_CONNECTORS_V2", + "outputs": [ + { + "internalType": "contract IDSAConnectorsV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ETH_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FLUID_RESERVE", + "outputs": [ + { + "internalType": "contract IFluidReserveContract", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FLUID_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GOVERNOR", + "outputs": [ + { + "internalType": "contract IGovernorBravo", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "IETHV2", + "outputs": [ + { + "internalType": "contract ILite", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "JRUSDE_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LENDING_FACTORY", + "outputs": [ + { + "internalType": "contract IFluidLendingFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIQUIDITY", + "outputs": [ + { + "internalType": "contract IFluidLiquidityAdmin", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OLD_USER_MODULE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OSETH_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAXG_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSAL_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSER_AVO_MULTISIG", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSER_AVO_MULTISIG_2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSER_AVO_MULTISIG_3", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSER_AVO_MULTISIG_4", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSER_AVO_MULTISIG_5", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESERVE_CONTRACT_PROXY", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REUSD_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RLP_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SMART_LENDING_FACTORY", + "outputs": [ + { + "internalType": "contract IFluidSmartLendingFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SRUSDE_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STABLE_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TEAM_MULTISIG", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TEAM_MULTISIG_2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TIMELOCK", + "outputs": [ + { + "internalType": "contract ITimelock", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TREASURY", + "outputs": [ + { + "internalType": "contract IDSAV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VAULT_FACTORY", + "outputs": [ + { + "internalType": "contract IFluidVaultFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "XAUT_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "action_", + "type": "uint256" + } + ], + "name": "actionStatus", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "csUSDL_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dummyImplementationAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dummyImplementationAddressLocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ezETH_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dexId_", + "type": "uint256" + } + ], + "name": "getDexAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getFTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProposalCreationTime", + "outputs": [ + { + "internalType": "uint40", + "name": "", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInUSD", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isSupply", + "type": "bool" + } + ], + "name": "getRawAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dexId_", + "type": "uint256" + } + ], + "name": "getSmartLendingAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultId_", + "type": "uint256" + } + ], + "name": "getVaultAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isProposalExecutable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lockDummyImplementationAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lockOnBehalfOfAuth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lockPausableDexAuth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lockPauseableAuth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lockUserModuleAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lockVaultFactoryOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mETH_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "onBehalfOfAuth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "onBehalfOfAuthLocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pausableDexAuth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pausableDexAuthLocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseableAuth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseableAuthLocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "description", + "type": "string" + } + ], + "name": "propose", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rsETH_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sUSDe_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sUSDs_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "actionsToSkip_", + "type": "uint256[]" + } + ], + "name": "setActionsToSkip", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dummyImplementationAddress_", + "type": "address" + } + ], + "name": "setDummyImplementationAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "onBehalfOfAuth_", + "type": "address" + } + ], + "name": "setOnBehalfOfAuth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pausableDexAuth_", + "type": "address" + } + ], + "name": "setPausableDexAuth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pauseableAuth_", + "type": "address" + } + ], + "name": "setPauseableAuth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint40", + "name": "proposalCreationTime_", + "type": "uint40" + } + ], + "name": "setProposalCreationTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "userModuleAddress_", + "type": "address" + } + ], + "name": "setUserModuleAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vaultFactoryOwner_", + "type": "address" + } + ], + "name": "setVaultFactoryOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "syrupUSDC_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "syrupUSDT_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "isExecutable_", + "type": "bool" + } + ], + "name": "toggleExecutable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "userModuleAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "userModuleAddressLocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultFactoryOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultFactoryOwnerLocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "verifyProposal", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weETH_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weETHs_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wstETH_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wstUSR_USD_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60a0604052600280546001600160a01b0319908116909155600380548216905560048054821690556005805482169055600680548216905560078054909116905534801561004b575f80fd5b503060805260805161449c6100fb5f395f818161098f01528181611b7201528181611cec0152818161207d01528181612160015281816126b101528181612729015281816128950152818161290d01528181612c5c01528181612d3601528181612dae01528181612ed201528181612f4a015281816131150152818161318d015281816132bc01528181613415015281816134e40152818161355c0152818161364401526136bc015261449c5ff3fe608060405234801561000f575f80fd5b506004361061049a575f3560e01c8063798d5ba311610263578063a90558361161014b578063c60dc265116100ca578063f53eddcc1161008f578063f53eddcc146109df578063f6370aa9146109fa578063f858b9b814610a04578063f88ed60c14610a18578063fb0ae91814610a33578063fcee0c9814610a46575f80fd5b8063c60dc26514610977578063cc025f7c1461098a578063d5818ec7146109b1578063e6bd26a2146109b9578063ed3660c5146109cc575f80fd5b8063b788f3a111610110578063b788f3a114610922578063bc3301a814610936578063bd8e486514610940578063bffa7f0f14610954578063c38b0f661461096f575f80fd5b8063a9055836146108ff578063aa98df3914610907578063ae68032b1461091a578063b6966495146106df578063b753428b146104c3575f80fd5b806396db7d5c116101e25780639ef94737116101a75780639ef9473714610887578063a45e1e7f1461089f578063a4d7866e146108a7578063a5caf0f6146108af578063a64f5693146108d1578063a7a60914146108ec575f80fd5b806396db7d5c146108325780639781a8ca1461083c57806397b87b4a146108465780639835a0bd146108615780639d3d2a7814610874575f80fd5b806383f5d77a1161022857806383f5d77a146104f9578063841d2699146107d6578063847b575b146107e957806395861bd7146107fc57806396bac93114610817575f80fd5b8063798d5ba31461076757806379b79a801461077a5780637aadef8b1461078d5780637e2f35fa146107a857806381c8c425146107c3575f80fd5b80633484818b1161038657806358f2552e116103055780636521e19f116102ca5780636521e19f1461071c57806366760d7d146105145780636dc0ae22146107265780637000778e14610741578063727a7c841461074b578063752f1e3114610753575f80fd5b806358f2552e146106df5780635c517457146106fa5780636146195414610702578063623007321461070a57806364e9d56714610714575f80fd5b80634ca254251161034b5780634ca254251461066f578063533e0b3f146106825780635689daec14610695578063588c77e6146106b057806358bf3112146106cb575f80fd5b80633484818b1461061c5780633b80188f14610626578063444386141461063957806348bbb5571461064c57806349af5a9f14610667575f80fd5b806312e366aa1161041d57806325ad7f4d116103e257806325ad7f4d146105b05780632861c7d1146105cb57806328787d00146104c35780632b54c373146105e65780632d2c5565146105ee5780633427355814610609575f80fd5b806312e366aa146105655780631392d4ee1461057857806317c1ac9e1461058b578063194c0e181461059e5780631bbc51a7146105a8575f80fd5b80630bc9136e116104635780630bc9136e146104f95780630e6a204c146105015780630e8043aa14610516578063103f29071461052a57806311ae7a141461055d575f80fd5b8062623d7d1461049e5780630251eb11146104b9578063040e7a80146104c35780630731dc99146104cb5780630b396e66146104ef575b5f80fd5b6104a660db81565b6040519081526020015b60405180910390f35b6104a6620474a081565b6104a6606481565b6007546104df90600160b81b900460ff1681565b60405190151581526020016104b0565b6104a662048c1081565b6104a6607e81565b61051461050f366004613bd6565b610a61565b005b6007546104df90600160a01b900460ff1681565b61054573324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d81565b6040516001600160a01b0390911681526020016104b0565b6104a6607881565b610545610573366004613bf8565b610ab7565b5f5465010000000000900460ff166104df565b600554610545906001600160a01b031681565b6104a66205747c81565b6104a6606e81565b610545739efde135ca4832abf0408c44c6f5f370eb0f35e881565b6105457352aa899454998be5b000ad077a46bbe360f4e49781565b6104a6606781565b6105457328849d2b63fa8d361e5fc15cb8abb13019884d0981565b600754610545906001600160a01b031681565b6104a662062e0881565b610514610634366004613c23565b610b32565b610514610647366004613c23565b610baa565b61054573e7eb63a8b6392481a9fdebb108cfd580dc8664d381565b610514610c22565b61051461067d366004613c23565b610c63565b600354610545906001600160a01b031681565b610545732e4015880367b7c2613df77f816739d97a8c46ad81565b610545735c43aac965ff230ac1cf63e924d0153291d78bad81565b6007546104df90600160c81b900460ff1681565b61054573264786ef916af64a1db19f513f24a3681734ce9281565b610514610cdb565b610514610d1c565b6104a662030d4081565b6104a6606c81565b6104a6620493e081565b610545730204cd037b2ec03605cfdfe482d8e257c765fa1b81565b6104a662062a2081565b6104a6606a81565b6007546104df90600160b01b900460ff1681565b610514610775366004613c3e565b610d7e565b610514610788366004613c23565b610e0c565b610545732386dc45added673317ef068992f19421b481f4c81565b61054573059a94a72951c0ae1cc1ce3bf0db52421bbe821081565b6105146107d1366004613c23565b610e84565b6105456107e4366004613bf8565b610efc565b600454610545906001600160a01b031681565b61054573a0d3707c569ff8c87fa923d3823ec5d81c98be7881565b6105457354b91a0d94cb471f37f949c60f7fa7935b551d0381565b6104a66204a38081565b6104a66269492081565b6105457391716c4eda1fb55e84bf8b4c7085f84285c1908581565b600654610545906001600160a01b031681565b6104a6610882366004613cad565b610f36565b5f5460405164ffffffffff90911681526020016104b0565b6105146117b5565b6105146117f6565b6104df6108bd366004613bf8565b5f9081526001602052604090205460ff1690565b6105457397b0b3a8bdefe8cb9563a3c610019ad10db8ad1181565b6105146108fa366004613c23565b611837565b6104a6607281565b610514610915366004613d39565b6118af565b6104a6607081565b6105455f8051602061444783398151915281565b6104a66204ab5081565b6007546104df90600160c01b900460ff1681565b61054573a45f7bd6a5ff45d31aace6bcd3d426d9328cea0181565b610514611d55565b610545610985366004613c23565b611d96565b6105457f000000000000000000000000000000000000000000000000000000000000000081565b610514611e84565b6105456109c7366004613bf8565b611ec5565b600254610545906001600160a01b031681565b61054573e57227c7d5900165344b190fc7aa580bceb53b9b81565b6104a66204a76881565b6007546104df90600160a81b900460ff1681565b610545733daff61fe5cfb1f1b4ea7fba8173a58532ef184181565b610514610a41366004613dc8565b611eff565b610545731e2e1aed876f67fe4fd54090fd7b8f57ce23421981565b335f8051602061444783398151915214610a965760405162461bcd60e51b8152600401610a8d90613dec565b60405180910390fd5b5f8054911515650100000000000265ff000000000019909216919091179055565b604051630971b35560e11b8152600481018290525f907391716c4eda1fb55e84bf8b4c7085f84285c19085906312e366aa906024015b602060405180830381865afa158015610b08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2c9190613e17565b92915050565b335f8051602061444783398151915214610b5e5760405162461bcd60e51b8152600401610a8d90613dec565b600754600160a81b900460ff1615610b885760405162461bcd60e51b8152600401610a8d90613e32565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610bd65760405162461bcd60e51b8152600401610a8d90613dec565b600754600160b81b900460ff1615610c005760405162461bcd60e51b8152600401610a8d90613e32565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610c4e5760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60a01b1916600160a01b179055565b335f8051602061444783398151915214610c8f5760405162461bcd60e51b8152600401610a8d90613dec565b600754600160c01b900460ff1615610cb95760405162461bcd60e51b8152600401610a8d90613e32565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610d075760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60a81b1916600160a81b179055565b610d24612025565b610d2c612147565b610d34612698565b610d3c61287c565b610d44612c44565b610d4c612d1d565b610d54612eb9565b610d5c6130fc565b610d646132a3565b610d6c6133fc565b610d746134cb565b610d7c61362b565b565b335f8051602061444783398151915214610daa5760405162461bcd60e51b8152600401610a8d90613dec565b5f5b81811015610e07576001805f858585818110610dca57610dca613e52565b9050602002013581526020019081526020015f205f6101000a81548160ff0219169083151502179055508080610dff90613e7a565b915050610dac565b505050565b335f8051602061444783398151915214610e385760405162461bcd60e51b8152600401610a8d90613dec565b600754600160c81b900460ff1615610e625760405162461bcd60e51b8152600401610a8d90613e32565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610eb05760405162461bcd60e51b8152600401610a8d90613dec565b600754600160b01b900460ff1615610eda5760405162461bcd60e51b8152600401610a8d90613e32565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60405163841d269960e01b8152600481018290525f9073e57227c7d5900165344b190fc7aa580bceb53b9b9063841d269990602401610aed565b5f8084118015610f4557505f83115b15610f925760405162461bcd60e51b815260206004820181905260248201527f626f74682075736420616e6420616d6f756e7420617265206e6f74207a65726f6044820152606401610a8d565b604080516001600160a01b03871660208083019190915260058284015282518083038401815260608301938490528051910120632d71cdb960e21b90925260648101919091525f907352aa899454998be5b000ad077a46bbe360f4e4979063b5c736e490608401602060405180830381865afa158015611014573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110389190613e92565b90505f80611045836137d9565b90925090505f601273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038b1601611080575062030d4090506012611736565b737f39c581f595b53c5cb19bd0b3f8da6c935e2c9f196001600160a01b038b16016110b357506205747c90506012611736565b73cd5fe23c85820f7b72d0926fc9b05b43e359b7ed196001600160a01b038b16016110e657506204a76890506012611736565b73a1290d69c65a6fe4df752f95823fae25cb99e5a6196001600160a01b038b1601611119575062048c1090506012611736565b73917cee801a67f933f2e6b33fc0cd1ed2d5909d87196001600160a01b038b160161114c5750620474a090506012611736565b73d5f7838f5c461feff7fe49ea5ebaf7728bb0adf9196001600160a01b038b160161117f57506204a38090506012611736565b73bf5495efe5db9ce00f80364c8b423567e58d210f196001600160a01b038b16016111b25750620493e090506012611736565b73f1c9acdc66974dfb6decb12aa385b9cd01190e37196001600160a01b038b16016111e557506204ab5090506012611736565b6001600160a01b038a1673cbb7c0000ab88b473b1f5afd9ef808440eed33bf148061122c57506001600160a01b038a16732260fac5e5542a773aa44fbcfedf7c193bc2c599145b8061125357506001600160a01b038a1673657e8c867d8b37dcc18fa4caead9c45eb088c642145b8061127a57506001600160a01b038a16738236a87084f8b84306f72007f36f2618a5634494145b1561128d57506269492090506008611736565b7318084fba666a33d37592fa2633fd49a74dd93a87196001600160a01b038b16016112c057506269492090506012611736565b6001600160a01b038a1673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48148061130757506001600160a01b038a1673dac17f958d2ee523a2206206994597c13d831ec7145b156113185750606490506006611736565b739d39a5de30e57443bff2a8307a4256c8797a3496196001600160a01b038b16016113495750607890506012611736565b73a3931d71877c0e7a3148cb7eb4463524fec27fbc196001600160a01b038b160161137a5750606c90506012611736565b73356b8d89c1e1239cbbb9de4815c39a1474d5ba7c196001600160a01b038b16016113ab5750606e90506006611736565b7380ac24aa929eaf5013f6436cda2a7ba190f5cc0a196001600160a01b038b16016113dc5750607290506006611736565b735086bf358635b81d8c47c66d1c8b9e567db70c71196001600160a01b038b160161140d5750606a90506012611736565b73beefc011e94f43b8b7b455ebab290c7ab4e216f0196001600160a01b038b160161143e5750606790506012611736565b73c58d044404d8b14e953c115e67823784dea53d8e196001600160a01b038b160161146f5750606490506012611736565b733d7d6fdf07ee548b939a80edbc9b2256d0cdc002196001600160a01b038b16016114a05750606490506012611736565b6001600160a01b038a167340d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14806114e757506001600160a01b038a16734c9edd5852cd905f086c759e8383e09bff1e68b3145b8061150e57506001600160a01b038a167315700b564ca08d9439c58ca5053166e8317aa138145b8061153557506001600160a01b038a167366a1e37c9b0eaddca17d3662d6c05f4decf3e110145b8061155c57506001600160a01b038a167373a15fed60bf67631dc6cd7bc5b6e8da8190acf5145b8061158357506001600160a01b038a1673085780639cc2cacd35e474e71f4d000e2405d8f6145b806115aa57506001600160a01b038a1673b01dd87b29d187f3e3a4bf6cdaebfb97f3d9ab98145b806115d157506001600160a01b038a167348f9e38f3070ad8945dfeae3fa70987722e3d89c145b806115f857506001600160a01b038a1673c139190f447e929f090edeb554d95abb8b18ac1c145b156116095750606490506012611736565b736f40d4a6237c257fff2db00fa0510deeecd303ea196001600160a01b038b160161163a575060db90506012611736565b731202f5c7b4b9e47a1a484e8b270be34dbbc75054196001600160a01b038b160161166b5750607090506012611736565b734956b52ae2ff65d74ca2d61207523288e4528f95196001600160a01b038b160161169c5750607e90506012611736565b7368749665ff8d2d112fa859aa293f07a622782f37196001600160a01b038b16016116cf575062062a2090506006611736565b7345804880de22913dafe09f4980848ece6ecbaf77196001600160a01b038b1601611702575062062e0890506012611736565b60405162461bcd60e51b81526020600482015260096024820152681b9bdd0b599bdd5b9960ba1b6044820152606401610a8d565b5f876117425783611744565b845b90508915611773578061175c8b64e8d4a51000613ea9565b6117669190613ed4565b96505050505050506117ad565b606461177f8285613ea9565b6117899190613ed4565b61179483600a613fd3565b6117a38b64e8d4a51000613ea9565b61175c9190613ea9565b949350505050565b335f80516020614447833981519152146117e15760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60b01b1916600160b01b179055565b335f80516020614447833981519152146118225760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60c01b1916600160c01b179055565b335f80516020614447833981519152146118635760405162461bcd60e51b8152600401610a8d90613dec565b600754600160a01b900460ff161561188d5760405162461bcd60e51b8152600401610a8d90613e32565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea0114806118dd5750335f80516020614447833981519152145b806118fb57503073059a94a72951c0ae1cc1ce3bf0db52421bbe8210145b80611919575030739efde135ca4832abf0408c44c6f5f370eb0f35e8145b80611937575030735c43aac965ff230ac1cf63e924d0153291d78bad145b80611955575030733daff61fe5cfb1f1b4ea7fba8173a58532ef1841145b8061197357503073e7eb63a8b6392481a9fdebb108cfd580dc8664d3145b6119b85760405162461bcd60e51b81526020600482015260166024820152751b5cd9cb9cd95b99195c8b5b9bdd0b585b1b1bddd95960521b6044820152606401610a8d565b6040805160018082528183019092525f9082602080830190803683370190505090505f8267ffffffffffffffff8111156119f4576119f4613cf4565b604051908082528060200260200182016040528015611a1d578160200160208202803683370190505b5090505f8367ffffffffffffffff811115611a3a57611a3a613cf4565b604051908082528060200260200182016040528015611a6d57816020015b6060815260200190600190039081611a585790505b5090505f8467ffffffffffffffff811115611a8a57611a8a613cf4565b604051908082528060200260200182016040528015611abd57816020015b6060815260200190600190039081611aa85790505b509050732386dc45added673317ef068992f19421b481f4c845f81518110611ae757611ae7613e52565b60200260200101906001600160a01b031690816001600160a01b0316815250505f835f81518110611b1a57611b1a613e52565b60200260200101818152505060405180606001604052806024815260200161442360249139825f81518110611b5157611b51613e52565b602090810291909101810191909152604080515f81529182018152611b99917f0000000000000000000000000000000000000000000000000000000000000000918101614021565b604051602081830303815290604052815f81518110611bba57611bba613e52565b6020908102919091010152604051636d4ab48d60e11b81525f90730204cd037b2ec03605cfdfe482d8e257c765fa1b9063da95691a90611c069088908890889088908e906004016140ed565b6020604051808303815f875af1158015611c22573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c469190613e92565b9050607e8114611c8f5760405162461bcd60e51b815260206004820152601460248201527350524f504f53414c5f49535f4e4f545f53414d4560601b6044820152606401610a8d565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea011480611cbd5750335f80516020614447833981519152145b15611cd057611ccb42611eff565b611d4c565b604051631f615d2360e31b815264ffffffffff421660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fb0ae918906024015f604051808303815f87803b158015611d35575f80fd5b505af1158015611d47573d5f803e3d5ffd5b505050505b50505050505050565b335f8051602061444783398151915214611d815760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60b81b1916600160b81b179055565b5f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc1196001600160a01b03831601611e25576040805163bb4a64d360e01b81526001600160a01b03841660048201526024810191909152601060448201526f4e6174697665556e6465726c79696e6760801b60648201527354b91a0d94cb471f37f949c60f7fa7935b551d039063bb4a64d390608401610aed565b6040805163bb4a64d360e01b81526001600160a01b038416600482015260248101919091526006604482015265332a37b5b2b760d11b60648201527354b91a0d94cb471f37f949c60f7fa7935b551d039063bb4a64d390608401610aed565b335f8051602061444783398151915214611eb05760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60c81b1916600160c81b179055565b60405163735e935160e11b8152600481018290525f9073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d9063e6bd26a290602401610aed565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea011480611f2d5750335f80516020614447833981519152145b80611f4b57503373059a94a72951c0ae1cc1ce3bf0db52421bbe8210145b80611f69575033739efde135ca4832abf0408c44c6f5f370eb0f35e8145b80611f87575033735c43aac965ff230ac1cf63e924d0153291d78bad145b80611fa5575033733daff61fe5cfb1f1b4ea7fba8173a58532ef1841145b80611fc357503373e7eb63a8b6392481a9fdebb108cfd580dc8664d3145b6120085760405162461bcd60e51b81526020600482015260166024820152751b5cd9cb9cd95b99195c8b5b9bdd0b585b1b1bddd95960521b6044820152606401610a8d565b5f805464ffffffffff191664ffffffffff92909216919091179055565b30732386dc45added673317ef068992f19421b481f4c1461207b5760405162461bcd60e51b815260206004820152601060248201526f3737ba16bb30b634b216b1b0b63632b960811b6044820152606401610a8d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631392d4ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120fb919061418b565b610d7c5760405162461bcd60e51b815260206004820152601760248201527f70726f706f73616c2d6e6f742d65786563757461626c650000000000000000006044820152606401610a8d565b6040516352e5787b60e11b8152600160048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d1919061418b565b6126955773324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d637faa1d216121f9606e611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612227939291906141a6565b5f604051808303815f87803b15801561223e575f80fd5b505af1158015612250573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d21612281606f611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016122af939291906141a6565b5f604051808303815f87803b1580156122c6575f80fd5b505af11580156122d8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216123096070611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612337939291906141a6565b5f604051808303815f87803b15801561234e575f80fd5b505af1158015612360573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216123916085611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016123bf939291906141a6565b5f604051808303815f87803b1580156123d6575f80fd5b505af11580156123e8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216124196086611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612447939291906141a6565b5f604051808303815f87803b15801561245e575f80fd5b505af1158015612470573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216124a16087611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016124cf939291906141a6565b5f604051808303815f87803b1580156124e6575f80fd5b505af11580156124f8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d21612529608f611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612557939291906141a6565b5f604051808303815f87803b15801561256e575f80fd5b505af1158015612580573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216125b16090611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016125df939291906141a6565b5f604051808303815f87803b1580156125f6575f80fd5b505af1158015612608573d5f803e3d5ffd5b505050507391716c4eda1fb55e84bf8b4c7085f84285c190856001600160a01b03166378c7e138612639601b610ab7565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612667939291906141a6565b5f604051808303815f87803b15801561267e575f80fd5b505af1158015612690573d5f803e3d5ffd5b505050505b50565b6040516352e5787b60e11b8152600260048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156126fe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612722919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ed3660c56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612783573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127a79190613e17565b90506001600160a01b0381166127f55760405162461bcd60e51b81526020600482015260136024820152721d5cd95c8b5b5bd91d5b194b5b9bdd0b5cd95d606a1b6044820152606401610a8d565b604051633ff8b31d60e01b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201526001600160a01b03821660248201527352aa899454998be5b000ad077a46bbe360f4e49790633ff8b31d906044015b5f604051808303815f87803b158015612862575f80fd5b505af1158015612874573d5f803e3d5ffd5b505050505050565b6040516352e5787b60e11b8152600360048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156128e2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612906919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ed3660c56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061298b9190613e17565b90506001600160a01b0381166129d95760405162461bcd60e51b81526020600482015260136024820152721d5cd95c8b5b5bd91d5b194b5b9bdd0b5cd95d606a1b6044820152606401610a8d565b6040516311272db960e31b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201525f907352aa899454998be5b000ad077a46bbe360f4e497906389396dc8906024015f60405180830381865afa158015612a3b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612a6291908101906141ca565b80519091505f612a73826001614278565b67ffffffffffffffff811115612a8b57612a8b613cf4565b604051908082528060200260200182016040528015612ab4578160200160208202803683370190505b5090505f5b82811015612b1657838181518110612ad357612ad3613e52565b6020026020010151828281518110612aed57612aed613e52565b6001600160e01b031990921660209283029190910190910152612b0f81613e7a565b9050612ab9565b507fdacb5419b3a364d15c0a7f04c12b64c98b665a88e8f945fd69383fb36d00d2d2818381518110612b4a57612b4a613e52565b6001600160e01b0319929092166020928302919091019091015260405163110bad1960e11b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201527352aa899454998be5b000ad077a46bbe360f4e497906322175a32906024015f604051808303815f87803b158015612bc1575f80fd5b505af1158015612bd3573d5f803e3d5ffd5b50506040516378600da160e11b81527352aa899454998be5b000ad077a46bbe360f4e497925063f0c01b429150612c10908790859060040161428b565b5f604051808303815f87803b158015612c27575f80fd5b505af1158015612c39573d5f803e3d5ffd5b505050505050505050565b6040516352e5787b60e11b81526004808201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612ca9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ccd919061418b565b612695577352aa899454998be5b000ad077a46bbe360f4e4976001600160a01b031663981c829f6040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561267e575f80fd5b6040516352e5787b60e11b8152600560048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612d83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612da7919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663533e0b3f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e2c9190613e17565b90506001600160a01b038116612e795760405162461bcd60e51b8152602060048201526012602482015271191d5b5b5e4b5a5b5c1b0b5b9bdd0b5cd95d60721b6044820152606401610a8d565b60405163c39aa07d60e01b81526001600160a01b03821660048201527352aa899454998be5b000ad077a46bbe360f4e4979063c39aa07d9060240161284b565b6040516352e5787b60e11b8152600660048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612f1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f43919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663847b575b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fa4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fc89190613e17565b90506001600160a01b0381166130205760405162461bcd60e51b815260206004820152601960248201527f6f6e2d626568616c662d6f662d617574682d6e6f742d736574000000000000006044820152606401610a8d565b6040805160018082528183019092525f91816020015b604080518082019091525f80825260208201528152602001906001900390816130365790505090506040518060400160405280836001600160a01b0316815260200160011515815250815f8151811061309157613091613e52565b6020908102919091010152604051633f66feff60e01b81527352aa899454998be5b000ad077a46bbe360f4e49790633f66feff906130d39084906004016142ea565b5f604051808303815f87803b1580156130ea575f80fd5b505af1158015611d4c573d5f803e3d5ffd5b6040516352e5787b60e11b8152600760048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613162573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613186919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166317c1ac9e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061320b9190613e17565b90506001600160a01b0381166132635760405162461bcd60e51b815260206004820152601b60248201527f7661756c742d666163746f72792d6f776e65722d6e6f742d73657400000000006044820152606401610a8d565b60405163f2fde38b60e01b81526001600160a01b038216600482015273324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d9063f2fde38b9060240161284b565b6040516352e5787b60e11b8152600860048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613309573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061332d919061418b565b6126955761335861333e606e611ec5565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486139ce565b61337f613365606f611ec5565b73dac17f958d2ee523a2206206994597c13d831ec76139ce565b6133a661338c6070611ec5565b7340d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6139ce565b6133b361333e6085611ec5565b5f6133be6002610ab7565b90505f6133cb6022610ab7565b90506133e0826133db6086611ec5565b613ae9565b6133ee826133db608f611ec5565b610e07816133db6090611ec5565b6040516352e5787b60e11b8152600960048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613462573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613486919061418b565b61269557613494601b610ab7565b6001600160a01b03166382df16526040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561267e575f80fd5b6040516352e5787b60e11b8152600a60048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613531573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613555919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639835a0bd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135b6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135da9190613e17565b90506001600160a01b0381166130205760405162461bcd60e51b81526020600482015260166024820152751c185d5cd958589b194b585d5d1a0b5b9bdd0b5cd95d60521b6044820152606401610a8d565b6040516352e5787b60e11b8152600b60048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613691573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136b5919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663342735586040518163ffffffff1660e01b8152600401602060405180830381865afa158015613716573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061373a9190613e17565b90506001600160a01b0381166137925760405162461bcd60e51b815260206004820152601960248201527f7061757361626c652d6465782d617574682d6e6f742d736574000000000000006044820152606401610a8d565b604051638f2db95d60e01b81526001600160a01b0382166004820152600160248201527391716c4eda1fb55e84bf8b4c7085f84285c1908590638f2db95d9060440161284b565b67ffffffffffffffff605b82901c811690609b83901c168115806137fb575080155b1561381e57604051636a86ba8960e11b8152620111716004820152602401610a8d565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480613848575082155b806138535750806001145b1561386057505050915091565b64496cebb80084840283020484019350617fff60db87901c1692508260010361388b57505050915091565b826001166001036138e05760019290921c91826c7e37be2022c0914b2680000000816138b9576138b9613ec0565b049250612710601e87901c613fff166b033b2e3c9fd0803ce800000085010204925061390d565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b806001166001036139445760011c61271081016b033b2e3c9fd0803ce800000082028161393c5761393c613ec0565b04905061397a565b60011c61271081016b033b2e3c9fd0803ce800000082028161396857613968613ec0565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b6040805160018082528183019092525f91816020015b613a326040518060e001604052805f6001600160a01b031681526020015f6001600160a01b031681526020015f60ff1681526020015f81526020015f81526020015f81526020015f81525090565b8152602001906001900390816139e45790505090506040518060e00160405280846001600160a01b03168152602001836001600160a01b03168152602001600160ff1681526020016001815260200162ffffff8152602001600a81526020016014815250815f81518110613aa857613aa8613e52565b602090810291909101015260405162dc47c360e11b81527352aa899454998be5b000ad077a46bbe360f4e497906301b88f86906130d3908490600401614336565b6040805160018082528183019092525f91816020015b613b356040518060a001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81525090565b815260200190600190039081613aff5790505090506040518060a00160405280836001600160a01b031681526020016001815260200162ffffff8152602001600a81526020016014815250815f81518110613b9257613b92613e52565b602090810291909101015260405163ba9af1e360e01b81526001600160a01b0384169063ba9af1e3906130d39084906004016143b9565b8015158114612695575f80fd5b5f60208284031215613be6575f80fd5b8135613bf181613bc9565b9392505050565b5f60208284031215613c08575f80fd5b5035919050565b6001600160a01b0381168114612695575f80fd5b5f60208284031215613c33575f80fd5b8135613bf181613c0f565b5f8060208385031215613c4f575f80fd5b823567ffffffffffffffff80821115613c66575f80fd5b818501915085601f830112613c79575f80fd5b813581811115613c87575f80fd5b8660208260051b8501011115613c9b575f80fd5b60209290920196919550909350505050565b5f805f8060808587031215613cc0575f80fd5b8435613ccb81613c0f565b935060208501359250604085013591506060850135613ce981613bc9565b939692955090935050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613d3157613d31613cf4565b604052919050565b5f6020808385031215613d4a575f80fd5b823567ffffffffffffffff80821115613d61575f80fd5b818501915085601f830112613d74575f80fd5b813581811115613d8657613d86613cf4565b613d98601f8201601f19168501613d08565b91508082528684828501011115613dad575f80fd5b80848401858401375f90820190930192909252509392505050565b5f60208284031215613dd8575f80fd5b813564ffffffffff81168114613bf1575f80fd5b6020808252601190820152706e6f742d7465616d2d6d756c746973696760781b604082015260600190565b5f60208284031215613e27575f80fd5b8151613bf181613c0f565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201613e8b57613e8b613e66565b5060010190565b5f60208284031215613ea2575f80fd5b5051919050565b8082028115828204841417610b2c57610b2c613e66565b634e487b7160e01b5f52601260045260245ffd5b5f82613eee57634e487b7160e01b5f52601260045260245ffd5b500490565b600181815b80851115613f2d57815f1904821115613f1357613f13613e66565b80851615613f2057918102915b93841c9390800290613ef8565b509250929050565b5f82613f4357506001610b2c565b81613f4f57505f610b2c565b8160018114613f655760028114613f6f57613f8b565b6001915050610b2c565b60ff841115613f8057613f80613e66565b50506001821b610b2c565b5060208310610133831016604e8410600b8410161715613fae575081810a610b2c565b613fb88383613ef3565b805f1904821115613fcb57613fcb613e66565b029392505050565b5f613bf18383613f35565b5f81518084525f5b8181101561400257602081850181015186830182015201613fe6565b505f602082860101526020601f19601f83011685010191505092915050565b60018060a01b038316815260606020820152600960608201526865786563757465282960b81b608082015260a060408201525f6117ad60a0830184613fde565b5f8151808452602080850194508084015f5b8381101561408f57815187529582019590820190600101614073565b509495945050505050565b5f81518084526020808501808196508360051b810191508286015f5b858110156140e05782840389526140ce848351613fde565b988501989350908401906001016140b6565b5091979650505050505050565b60a080825286519082018190525f9060209060c0840190828a01845b8281101561412e5781516001600160a01b031684529284019290840190600101614109565b505050838103828501526141428189614061565b9150508281036040840152614157818761409a565b9050828103606084015261416b818661409a565b9050828103608084015261417f8185613fde565b98975050505050505050565b5f6020828403121561419b575f80fd5b8151613bf181613bc9565b6001600160a01b039384168152919092166020820152901515604082015260600190565b5f60208083850312156141db575f80fd5b825167ffffffffffffffff808211156141f2575f80fd5b818501915085601f830112614205575f80fd5b81518181111561421757614217613cf4565b8060051b9150614228848301613d08565b8181529183018401918481019088841115614241575f80fd5b938501935b8385101561417f57845192506001600160e01b031983168314614268575f8081fd5b8282529385019390850190614246565b80820180821115610b2c57610b2c613e66565b6001600160a01b03831681526040602080830182905283519183018290525f9184820191906060850190845b818110156142dd5784516001600160e01b031916835293830193918301916001016142b7565b5090979650505050505050565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b031685528601511515868501529284019290850190600101614306565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b0390811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0808201519086015260c0908101519085015260e09093019290850190600101614352565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080908101519085015260a090930192908501906001016143d556fe657865637574655061796c6f616428616464726573732c737472696e672c6279746573290000000000000000000000004f6f977acdd1177dcd81ab83074855ecb9c2d49ea2646970667358221220cc4fd4303a28ea03114d3976a3e0fae3acfc265462710b0fd7d5048563ccdd2064736f6c63430008150033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061049a575f3560e01c8063798d5ba311610263578063a90558361161014b578063c60dc265116100ca578063f53eddcc1161008f578063f53eddcc146109df578063f6370aa9146109fa578063f858b9b814610a04578063f88ed60c14610a18578063fb0ae91814610a33578063fcee0c9814610a46575f80fd5b8063c60dc26514610977578063cc025f7c1461098a578063d5818ec7146109b1578063e6bd26a2146109b9578063ed3660c5146109cc575f80fd5b8063b788f3a111610110578063b788f3a114610922578063bc3301a814610936578063bd8e486514610940578063bffa7f0f14610954578063c38b0f661461096f575f80fd5b8063a9055836146108ff578063aa98df3914610907578063ae68032b1461091a578063b6966495146106df578063b753428b146104c3575f80fd5b806396db7d5c116101e25780639ef94737116101a75780639ef9473714610887578063a45e1e7f1461089f578063a4d7866e146108a7578063a5caf0f6146108af578063a64f5693146108d1578063a7a60914146108ec575f80fd5b806396db7d5c146108325780639781a8ca1461083c57806397b87b4a146108465780639835a0bd146108615780639d3d2a7814610874575f80fd5b806383f5d77a1161022857806383f5d77a146104f9578063841d2699146107d6578063847b575b146107e957806395861bd7146107fc57806396bac93114610817575f80fd5b8063798d5ba31461076757806379b79a801461077a5780637aadef8b1461078d5780637e2f35fa146107a857806381c8c425146107c3575f80fd5b80633484818b1161038657806358f2552e116103055780636521e19f116102ca5780636521e19f1461071c57806366760d7d146105145780636dc0ae22146107265780637000778e14610741578063727a7c841461074b578063752f1e3114610753575f80fd5b806358f2552e146106df5780635c517457146106fa5780636146195414610702578063623007321461070a57806364e9d56714610714575f80fd5b80634ca254251161034b5780634ca254251461066f578063533e0b3f146106825780635689daec14610695578063588c77e6146106b057806358bf3112146106cb575f80fd5b80633484818b1461061c5780633b80188f14610626578063444386141461063957806348bbb5571461064c57806349af5a9f14610667575f80fd5b806312e366aa1161041d57806325ad7f4d116103e257806325ad7f4d146105b05780632861c7d1146105cb57806328787d00146104c35780632b54c373146105e65780632d2c5565146105ee5780633427355814610609575f80fd5b806312e366aa146105655780631392d4ee1461057857806317c1ac9e1461058b578063194c0e181461059e5780631bbc51a7146105a8575f80fd5b80630bc9136e116104635780630bc9136e146104f95780630e6a204c146105015780630e8043aa14610516578063103f29071461052a57806311ae7a141461055d575f80fd5b8062623d7d1461049e5780630251eb11146104b9578063040e7a80146104c35780630731dc99146104cb5780630b396e66146104ef575b5f80fd5b6104a660db81565b6040519081526020015b60405180910390f35b6104a6620474a081565b6104a6606481565b6007546104df90600160b81b900460ff1681565b60405190151581526020016104b0565b6104a662048c1081565b6104a6607e81565b61051461050f366004613bd6565b610a61565b005b6007546104df90600160a01b900460ff1681565b61054573324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d81565b6040516001600160a01b0390911681526020016104b0565b6104a6607881565b610545610573366004613bf8565b610ab7565b5f5465010000000000900460ff166104df565b600554610545906001600160a01b031681565b6104a66205747c81565b6104a6606e81565b610545739efde135ca4832abf0408c44c6f5f370eb0f35e881565b6105457352aa899454998be5b000ad077a46bbe360f4e49781565b6104a6606781565b6105457328849d2b63fa8d361e5fc15cb8abb13019884d0981565b600754610545906001600160a01b031681565b6104a662062e0881565b610514610634366004613c23565b610b32565b610514610647366004613c23565b610baa565b61054573e7eb63a8b6392481a9fdebb108cfd580dc8664d381565b610514610c22565b61051461067d366004613c23565b610c63565b600354610545906001600160a01b031681565b610545732e4015880367b7c2613df77f816739d97a8c46ad81565b610545735c43aac965ff230ac1cf63e924d0153291d78bad81565b6007546104df90600160c81b900460ff1681565b61054573264786ef916af64a1db19f513f24a3681734ce9281565b610514610cdb565b610514610d1c565b6104a662030d4081565b6104a6606c81565b6104a6620493e081565b610545730204cd037b2ec03605cfdfe482d8e257c765fa1b81565b6104a662062a2081565b6104a6606a81565b6007546104df90600160b01b900460ff1681565b610514610775366004613c3e565b610d7e565b610514610788366004613c23565b610e0c565b610545732386dc45added673317ef068992f19421b481f4c81565b61054573059a94a72951c0ae1cc1ce3bf0db52421bbe821081565b6105146107d1366004613c23565b610e84565b6105456107e4366004613bf8565b610efc565b600454610545906001600160a01b031681565b61054573a0d3707c569ff8c87fa923d3823ec5d81c98be7881565b6105457354b91a0d94cb471f37f949c60f7fa7935b551d0381565b6104a66204a38081565b6104a66269492081565b6105457391716c4eda1fb55e84bf8b4c7085f84285c1908581565b600654610545906001600160a01b031681565b6104a6610882366004613cad565b610f36565b5f5460405164ffffffffff90911681526020016104b0565b6105146117b5565b6105146117f6565b6104df6108bd366004613bf8565b5f9081526001602052604090205460ff1690565b6105457397b0b3a8bdefe8cb9563a3c610019ad10db8ad1181565b6105146108fa366004613c23565b611837565b6104a6607281565b610514610915366004613d39565b6118af565b6104a6607081565b6105455f8051602061444783398151915281565b6104a66204ab5081565b6007546104df90600160c01b900460ff1681565b61054573a45f7bd6a5ff45d31aace6bcd3d426d9328cea0181565b610514611d55565b610545610985366004613c23565b611d96565b6105457f000000000000000000000000000000000000000000000000000000000000000081565b610514611e84565b6105456109c7366004613bf8565b611ec5565b600254610545906001600160a01b031681565b61054573e57227c7d5900165344b190fc7aa580bceb53b9b81565b6104a66204a76881565b6007546104df90600160a81b900460ff1681565b610545733daff61fe5cfb1f1b4ea7fba8173a58532ef184181565b610514610a41366004613dc8565b611eff565b610545731e2e1aed876f67fe4fd54090fd7b8f57ce23421981565b335f8051602061444783398151915214610a965760405162461bcd60e51b8152600401610a8d90613dec565b60405180910390fd5b5f8054911515650100000000000265ff000000000019909216919091179055565b604051630971b35560e11b8152600481018290525f907391716c4eda1fb55e84bf8b4c7085f84285c19085906312e366aa906024015b602060405180830381865afa158015610b08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2c9190613e17565b92915050565b335f8051602061444783398151915214610b5e5760405162461bcd60e51b8152600401610a8d90613dec565b600754600160a81b900460ff1615610b885760405162461bcd60e51b8152600401610a8d90613e32565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610bd65760405162461bcd60e51b8152600401610a8d90613dec565b600754600160b81b900460ff1615610c005760405162461bcd60e51b8152600401610a8d90613e32565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610c4e5760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60a01b1916600160a01b179055565b335f8051602061444783398151915214610c8f5760405162461bcd60e51b8152600401610a8d90613dec565b600754600160c01b900460ff1615610cb95760405162461bcd60e51b8152600401610a8d90613e32565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610d075760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60a81b1916600160a81b179055565b610d24612025565b610d2c612147565b610d34612698565b610d3c61287c565b610d44612c44565b610d4c612d1d565b610d54612eb9565b610d5c6130fc565b610d646132a3565b610d6c6133fc565b610d746134cb565b610d7c61362b565b565b335f8051602061444783398151915214610daa5760405162461bcd60e51b8152600401610a8d90613dec565b5f5b81811015610e07576001805f858585818110610dca57610dca613e52565b9050602002013581526020019081526020015f205f6101000a81548160ff0219169083151502179055508080610dff90613e7a565b915050610dac565b505050565b335f8051602061444783398151915214610e385760405162461bcd60e51b8152600401610a8d90613dec565b600754600160c81b900460ff1615610e625760405162461bcd60e51b8152600401610a8d90613e32565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610eb05760405162461bcd60e51b8152600401610a8d90613dec565b600754600160b01b900460ff1615610eda5760405162461bcd60e51b8152600401610a8d90613e32565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60405163841d269960e01b8152600481018290525f9073e57227c7d5900165344b190fc7aa580bceb53b9b9063841d269990602401610aed565b5f8084118015610f4557505f83115b15610f925760405162461bcd60e51b815260206004820181905260248201527f626f74682075736420616e6420616d6f756e7420617265206e6f74207a65726f6044820152606401610a8d565b604080516001600160a01b03871660208083019190915260058284015282518083038401815260608301938490528051910120632d71cdb960e21b90925260648101919091525f907352aa899454998be5b000ad077a46bbe360f4e4979063b5c736e490608401602060405180830381865afa158015611014573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110389190613e92565b90505f80611045836137d9565b90925090505f601273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038b1601611080575062030d4090506012611736565b737f39c581f595b53c5cb19bd0b3f8da6c935e2c9f196001600160a01b038b16016110b357506205747c90506012611736565b73cd5fe23c85820f7b72d0926fc9b05b43e359b7ed196001600160a01b038b16016110e657506204a76890506012611736565b73a1290d69c65a6fe4df752f95823fae25cb99e5a6196001600160a01b038b1601611119575062048c1090506012611736565b73917cee801a67f933f2e6b33fc0cd1ed2d5909d87196001600160a01b038b160161114c5750620474a090506012611736565b73d5f7838f5c461feff7fe49ea5ebaf7728bb0adf9196001600160a01b038b160161117f57506204a38090506012611736565b73bf5495efe5db9ce00f80364c8b423567e58d210f196001600160a01b038b16016111b25750620493e090506012611736565b73f1c9acdc66974dfb6decb12aa385b9cd01190e37196001600160a01b038b16016111e557506204ab5090506012611736565b6001600160a01b038a1673cbb7c0000ab88b473b1f5afd9ef808440eed33bf148061122c57506001600160a01b038a16732260fac5e5542a773aa44fbcfedf7c193bc2c599145b8061125357506001600160a01b038a1673657e8c867d8b37dcc18fa4caead9c45eb088c642145b8061127a57506001600160a01b038a16738236a87084f8b84306f72007f36f2618a5634494145b1561128d57506269492090506008611736565b7318084fba666a33d37592fa2633fd49a74dd93a87196001600160a01b038b16016112c057506269492090506012611736565b6001600160a01b038a1673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48148061130757506001600160a01b038a1673dac17f958d2ee523a2206206994597c13d831ec7145b156113185750606490506006611736565b739d39a5de30e57443bff2a8307a4256c8797a3496196001600160a01b038b16016113495750607890506012611736565b73a3931d71877c0e7a3148cb7eb4463524fec27fbc196001600160a01b038b160161137a5750606c90506012611736565b73356b8d89c1e1239cbbb9de4815c39a1474d5ba7c196001600160a01b038b16016113ab5750606e90506006611736565b7380ac24aa929eaf5013f6436cda2a7ba190f5cc0a196001600160a01b038b16016113dc5750607290506006611736565b735086bf358635b81d8c47c66d1c8b9e567db70c71196001600160a01b038b160161140d5750606a90506012611736565b73beefc011e94f43b8b7b455ebab290c7ab4e216f0196001600160a01b038b160161143e5750606790506012611736565b73c58d044404d8b14e953c115e67823784dea53d8e196001600160a01b038b160161146f5750606490506012611736565b733d7d6fdf07ee548b939a80edbc9b2256d0cdc002196001600160a01b038b16016114a05750606490506012611736565b6001600160a01b038a167340d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14806114e757506001600160a01b038a16734c9edd5852cd905f086c759e8383e09bff1e68b3145b8061150e57506001600160a01b038a167315700b564ca08d9439c58ca5053166e8317aa138145b8061153557506001600160a01b038a167366a1e37c9b0eaddca17d3662d6c05f4decf3e110145b8061155c57506001600160a01b038a167373a15fed60bf67631dc6cd7bc5b6e8da8190acf5145b8061158357506001600160a01b038a1673085780639cc2cacd35e474e71f4d000e2405d8f6145b806115aa57506001600160a01b038a1673b01dd87b29d187f3e3a4bf6cdaebfb97f3d9ab98145b806115d157506001600160a01b038a167348f9e38f3070ad8945dfeae3fa70987722e3d89c145b806115f857506001600160a01b038a1673c139190f447e929f090edeb554d95abb8b18ac1c145b156116095750606490506012611736565b736f40d4a6237c257fff2db00fa0510deeecd303ea196001600160a01b038b160161163a575060db90506012611736565b731202f5c7b4b9e47a1a484e8b270be34dbbc75054196001600160a01b038b160161166b5750607090506012611736565b734956b52ae2ff65d74ca2d61207523288e4528f95196001600160a01b038b160161169c5750607e90506012611736565b7368749665ff8d2d112fa859aa293f07a622782f37196001600160a01b038b16016116cf575062062a2090506006611736565b7345804880de22913dafe09f4980848ece6ecbaf77196001600160a01b038b1601611702575062062e0890506012611736565b60405162461bcd60e51b81526020600482015260096024820152681b9bdd0b599bdd5b9960ba1b6044820152606401610a8d565b5f876117425783611744565b845b90508915611773578061175c8b64e8d4a51000613ea9565b6117669190613ed4565b96505050505050506117ad565b606461177f8285613ea9565b6117899190613ed4565b61179483600a613fd3565b6117a38b64e8d4a51000613ea9565b61175c9190613ea9565b949350505050565b335f80516020614447833981519152146117e15760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60b01b1916600160b01b179055565b335f80516020614447833981519152146118225760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60c01b1916600160c01b179055565b335f80516020614447833981519152146118635760405162461bcd60e51b8152600401610a8d90613dec565b600754600160a01b900460ff161561188d5760405162461bcd60e51b8152600401610a8d90613e32565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea0114806118dd5750335f80516020614447833981519152145b806118fb57503073059a94a72951c0ae1cc1ce3bf0db52421bbe8210145b80611919575030739efde135ca4832abf0408c44c6f5f370eb0f35e8145b80611937575030735c43aac965ff230ac1cf63e924d0153291d78bad145b80611955575030733daff61fe5cfb1f1b4ea7fba8173a58532ef1841145b8061197357503073e7eb63a8b6392481a9fdebb108cfd580dc8664d3145b6119b85760405162461bcd60e51b81526020600482015260166024820152751b5cd9cb9cd95b99195c8b5b9bdd0b585b1b1bddd95960521b6044820152606401610a8d565b6040805160018082528183019092525f9082602080830190803683370190505090505f8267ffffffffffffffff8111156119f4576119f4613cf4565b604051908082528060200260200182016040528015611a1d578160200160208202803683370190505b5090505f8367ffffffffffffffff811115611a3a57611a3a613cf4565b604051908082528060200260200182016040528015611a6d57816020015b6060815260200190600190039081611a585790505b5090505f8467ffffffffffffffff811115611a8a57611a8a613cf4565b604051908082528060200260200182016040528015611abd57816020015b6060815260200190600190039081611aa85790505b509050732386dc45added673317ef068992f19421b481f4c845f81518110611ae757611ae7613e52565b60200260200101906001600160a01b031690816001600160a01b0316815250505f835f81518110611b1a57611b1a613e52565b60200260200101818152505060405180606001604052806024815260200161442360249139825f81518110611b5157611b51613e52565b602090810291909101810191909152604080515f81529182018152611b99917f0000000000000000000000000000000000000000000000000000000000000000918101614021565b604051602081830303815290604052815f81518110611bba57611bba613e52565b6020908102919091010152604051636d4ab48d60e11b81525f90730204cd037b2ec03605cfdfe482d8e257c765fa1b9063da95691a90611c069088908890889088908e906004016140ed565b6020604051808303815f875af1158015611c22573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c469190613e92565b9050607e8114611c8f5760405162461bcd60e51b815260206004820152601460248201527350524f504f53414c5f49535f4e4f545f53414d4560601b6044820152606401610a8d565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea011480611cbd5750335f80516020614447833981519152145b15611cd057611ccb42611eff565b611d4c565b604051631f615d2360e31b815264ffffffffff421660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fb0ae918906024015f604051808303815f87803b158015611d35575f80fd5b505af1158015611d47573d5f803e3d5ffd5b505050505b50505050505050565b335f8051602061444783398151915214611d815760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60b81b1916600160b81b179055565b5f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc1196001600160a01b03831601611e25576040805163bb4a64d360e01b81526001600160a01b03841660048201526024810191909152601060448201526f4e6174697665556e6465726c79696e6760801b60648201527354b91a0d94cb471f37f949c60f7fa7935b551d039063bb4a64d390608401610aed565b6040805163bb4a64d360e01b81526001600160a01b038416600482015260248101919091526006604482015265332a37b5b2b760d11b60648201527354b91a0d94cb471f37f949c60f7fa7935b551d039063bb4a64d390608401610aed565b335f8051602061444783398151915214611eb05760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60c81b1916600160c81b179055565b60405163735e935160e11b8152600481018290525f9073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d9063e6bd26a290602401610aed565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea011480611f2d5750335f80516020614447833981519152145b80611f4b57503373059a94a72951c0ae1cc1ce3bf0db52421bbe8210145b80611f69575033739efde135ca4832abf0408c44c6f5f370eb0f35e8145b80611f87575033735c43aac965ff230ac1cf63e924d0153291d78bad145b80611fa5575033733daff61fe5cfb1f1b4ea7fba8173a58532ef1841145b80611fc357503373e7eb63a8b6392481a9fdebb108cfd580dc8664d3145b6120085760405162461bcd60e51b81526020600482015260166024820152751b5cd9cb9cd95b99195c8b5b9bdd0b585b1b1bddd95960521b6044820152606401610a8d565b5f805464ffffffffff191664ffffffffff92909216919091179055565b30732386dc45added673317ef068992f19421b481f4c1461207b5760405162461bcd60e51b815260206004820152601060248201526f3737ba16bb30b634b216b1b0b63632b960811b6044820152606401610a8d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631392d4ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120fb919061418b565b610d7c5760405162461bcd60e51b815260206004820152601760248201527f70726f706f73616c2d6e6f742d65786563757461626c650000000000000000006044820152606401610a8d565b6040516352e5787b60e11b8152600160048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d1919061418b565b6126955773324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d637faa1d216121f9606e611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612227939291906141a6565b5f604051808303815f87803b15801561223e575f80fd5b505af1158015612250573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d21612281606f611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016122af939291906141a6565b5f604051808303815f87803b1580156122c6575f80fd5b505af11580156122d8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216123096070611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612337939291906141a6565b5f604051808303815f87803b15801561234e575f80fd5b505af1158015612360573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216123916085611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016123bf939291906141a6565b5f604051808303815f87803b1580156123d6575f80fd5b505af11580156123e8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216124196086611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612447939291906141a6565b5f604051808303815f87803b15801561245e575f80fd5b505af1158015612470573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216124a16087611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016124cf939291906141a6565b5f604051808303815f87803b1580156124e6575f80fd5b505af11580156124f8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d21612529608f611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612557939291906141a6565b5f604051808303815f87803b15801561256e575f80fd5b505af1158015612580573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216125b16090611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016125df939291906141a6565b5f604051808303815f87803b1580156125f6575f80fd5b505af1158015612608573d5f803e3d5ffd5b505050507391716c4eda1fb55e84bf8b4c7085f84285c190856001600160a01b03166378c7e138612639601b610ab7565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612667939291906141a6565b5f604051808303815f87803b15801561267e575f80fd5b505af1158015612690573d5f803e3d5ffd5b505050505b50565b6040516352e5787b60e11b8152600260048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156126fe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612722919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ed3660c56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612783573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127a79190613e17565b90506001600160a01b0381166127f55760405162461bcd60e51b81526020600482015260136024820152721d5cd95c8b5b5bd91d5b194b5b9bdd0b5cd95d606a1b6044820152606401610a8d565b604051633ff8b31d60e01b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201526001600160a01b03821660248201527352aa899454998be5b000ad077a46bbe360f4e49790633ff8b31d906044015b5f604051808303815f87803b158015612862575f80fd5b505af1158015612874573d5f803e3d5ffd5b505050505050565b6040516352e5787b60e11b8152600360048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156128e2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612906919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ed3660c56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061298b9190613e17565b90506001600160a01b0381166129d95760405162461bcd60e51b81526020600482015260136024820152721d5cd95c8b5b5bd91d5b194b5b9bdd0b5cd95d606a1b6044820152606401610a8d565b6040516311272db960e31b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201525f907352aa899454998be5b000ad077a46bbe360f4e497906389396dc8906024015f60405180830381865afa158015612a3b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612a6291908101906141ca565b80519091505f612a73826001614278565b67ffffffffffffffff811115612a8b57612a8b613cf4565b604051908082528060200260200182016040528015612ab4578160200160208202803683370190505b5090505f5b82811015612b1657838181518110612ad357612ad3613e52565b6020026020010151828281518110612aed57612aed613e52565b6001600160e01b031990921660209283029190910190910152612b0f81613e7a565b9050612ab9565b507fdacb5419b3a364d15c0a7f04c12b64c98b665a88e8f945fd69383fb36d00d2d2818381518110612b4a57612b4a613e52565b6001600160e01b0319929092166020928302919091019091015260405163110bad1960e11b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201527352aa899454998be5b000ad077a46bbe360f4e497906322175a32906024015f604051808303815f87803b158015612bc1575f80fd5b505af1158015612bd3573d5f803e3d5ffd5b50506040516378600da160e11b81527352aa899454998be5b000ad077a46bbe360f4e497925063f0c01b429150612c10908790859060040161428b565b5f604051808303815f87803b158015612c27575f80fd5b505af1158015612c39573d5f803e3d5ffd5b505050505050505050565b6040516352e5787b60e11b81526004808201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612ca9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ccd919061418b565b612695577352aa899454998be5b000ad077a46bbe360f4e4976001600160a01b031663981c829f6040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561267e575f80fd5b6040516352e5787b60e11b8152600560048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612d83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612da7919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663533e0b3f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e2c9190613e17565b90506001600160a01b038116612e795760405162461bcd60e51b8152602060048201526012602482015271191d5b5b5e4b5a5b5c1b0b5b9bdd0b5cd95d60721b6044820152606401610a8d565b60405163c39aa07d60e01b81526001600160a01b03821660048201527352aa899454998be5b000ad077a46bbe360f4e4979063c39aa07d9060240161284b565b6040516352e5787b60e11b8152600660048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612f1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f43919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663847b575b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fa4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fc89190613e17565b90506001600160a01b0381166130205760405162461bcd60e51b815260206004820152601960248201527f6f6e2d626568616c662d6f662d617574682d6e6f742d736574000000000000006044820152606401610a8d565b6040805160018082528183019092525f91816020015b604080518082019091525f80825260208201528152602001906001900390816130365790505090506040518060400160405280836001600160a01b0316815260200160011515815250815f8151811061309157613091613e52565b6020908102919091010152604051633f66feff60e01b81527352aa899454998be5b000ad077a46bbe360f4e49790633f66feff906130d39084906004016142ea565b5f604051808303815f87803b1580156130ea575f80fd5b505af1158015611d4c573d5f803e3d5ffd5b6040516352e5787b60e11b8152600760048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613162573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613186919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166317c1ac9e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061320b9190613e17565b90506001600160a01b0381166132635760405162461bcd60e51b815260206004820152601b60248201527f7661756c742d666163746f72792d6f776e65722d6e6f742d73657400000000006044820152606401610a8d565b60405163f2fde38b60e01b81526001600160a01b038216600482015273324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d9063f2fde38b9060240161284b565b6040516352e5787b60e11b8152600860048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613309573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061332d919061418b565b6126955761335861333e606e611ec5565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486139ce565b61337f613365606f611ec5565b73dac17f958d2ee523a2206206994597c13d831ec76139ce565b6133a661338c6070611ec5565b7340d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6139ce565b6133b361333e6085611ec5565b5f6133be6002610ab7565b90505f6133cb6022610ab7565b90506133e0826133db6086611ec5565b613ae9565b6133ee826133db608f611ec5565b610e07816133db6090611ec5565b6040516352e5787b60e11b8152600960048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613462573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613486919061418b565b61269557613494601b610ab7565b6001600160a01b03166382df16526040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561267e575f80fd5b6040516352e5787b60e11b8152600a60048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613531573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613555919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639835a0bd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135b6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135da9190613e17565b90506001600160a01b0381166130205760405162461bcd60e51b81526020600482015260166024820152751c185d5cd958589b194b585d5d1a0b5b9bdd0b5cd95d60521b6044820152606401610a8d565b6040516352e5787b60e11b8152600b60048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613691573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136b5919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663342735586040518163ffffffff1660e01b8152600401602060405180830381865afa158015613716573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061373a9190613e17565b90506001600160a01b0381166137925760405162461bcd60e51b815260206004820152601960248201527f7061757361626c652d6465782d617574682d6e6f742d736574000000000000006044820152606401610a8d565b604051638f2db95d60e01b81526001600160a01b0382166004820152600160248201527391716c4eda1fb55e84bf8b4c7085f84285c1908590638f2db95d9060440161284b565b67ffffffffffffffff605b82901c811690609b83901c168115806137fb575080155b1561381e57604051636a86ba8960e11b8152620111716004820152602401610a8d565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480613848575082155b806138535750806001145b1561386057505050915091565b64496cebb80084840283020484019350617fff60db87901c1692508260010361388b57505050915091565b826001166001036138e05760019290921c91826c7e37be2022c0914b2680000000816138b9576138b9613ec0565b049250612710601e87901c613fff166b033b2e3c9fd0803ce800000085010204925061390d565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b806001166001036139445760011c61271081016b033b2e3c9fd0803ce800000082028161393c5761393c613ec0565b04905061397a565b60011c61271081016b033b2e3c9fd0803ce800000082028161396857613968613ec0565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b6040805160018082528183019092525f91816020015b613a326040518060e001604052805f6001600160a01b031681526020015f6001600160a01b031681526020015f60ff1681526020015f81526020015f81526020015f81526020015f81525090565b8152602001906001900390816139e45790505090506040518060e00160405280846001600160a01b03168152602001836001600160a01b03168152602001600160ff1681526020016001815260200162ffffff8152602001600a81526020016014815250815f81518110613aa857613aa8613e52565b602090810291909101015260405162dc47c360e11b81527352aa899454998be5b000ad077a46bbe360f4e497906301b88f86906130d3908490600401614336565b6040805160018082528183019092525f91816020015b613b356040518060a001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81525090565b815260200190600190039081613aff5790505090506040518060a00160405280836001600160a01b031681526020016001815260200162ffffff8152602001600a81526020016014815250815f81518110613b9257613b92613e52565b602090810291909101015260405163ba9af1e360e01b81526001600160a01b0384169063ba9af1e3906130d39084906004016143b9565b8015158114612695575f80fd5b5f60208284031215613be6575f80fd5b8135613bf181613bc9565b9392505050565b5f60208284031215613c08575f80fd5b5035919050565b6001600160a01b0381168114612695575f80fd5b5f60208284031215613c33575f80fd5b8135613bf181613c0f565b5f8060208385031215613c4f575f80fd5b823567ffffffffffffffff80821115613c66575f80fd5b818501915085601f830112613c79575f80fd5b813581811115613c87575f80fd5b8660208260051b8501011115613c9b575f80fd5b60209290920196919550909350505050565b5f805f8060808587031215613cc0575f80fd5b8435613ccb81613c0f565b935060208501359250604085013591506060850135613ce981613bc9565b939692955090935050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613d3157613d31613cf4565b604052919050565b5f6020808385031215613d4a575f80fd5b823567ffffffffffffffff80821115613d61575f80fd5b818501915085601f830112613d74575f80fd5b813581811115613d8657613d86613cf4565b613d98601f8201601f19168501613d08565b91508082528684828501011115613dad575f80fd5b80848401858401375f90820190930192909252509392505050565b5f60208284031215613dd8575f80fd5b813564ffffffffff81168114613bf1575f80fd5b6020808252601190820152706e6f742d7465616d2d6d756c746973696760781b604082015260600190565b5f60208284031215613e27575f80fd5b8151613bf181613c0f565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201613e8b57613e8b613e66565b5060010190565b5f60208284031215613ea2575f80fd5b5051919050565b8082028115828204841417610b2c57610b2c613e66565b634e487b7160e01b5f52601260045260245ffd5b5f82613eee57634e487b7160e01b5f52601260045260245ffd5b500490565b600181815b80851115613f2d57815f1904821115613f1357613f13613e66565b80851615613f2057918102915b93841c9390800290613ef8565b509250929050565b5f82613f4357506001610b2c565b81613f4f57505f610b2c565b8160018114613f655760028114613f6f57613f8b565b6001915050610b2c565b60ff841115613f8057613f80613e66565b50506001821b610b2c565b5060208310610133831016604e8410600b8410161715613fae575081810a610b2c565b613fb88383613ef3565b805f1904821115613fcb57613fcb613e66565b029392505050565b5f613bf18383613f35565b5f81518084525f5b8181101561400257602081850181015186830182015201613fe6565b505f602082860101526020601f19601f83011685010191505092915050565b60018060a01b038316815260606020820152600960608201526865786563757465282960b81b608082015260a060408201525f6117ad60a0830184613fde565b5f8151808452602080850194508084015f5b8381101561408f57815187529582019590820190600101614073565b509495945050505050565b5f81518084526020808501808196508360051b810191508286015f5b858110156140e05782840389526140ce848351613fde565b988501989350908401906001016140b6565b5091979650505050505050565b60a080825286519082018190525f9060209060c0840190828a01845b8281101561412e5781516001600160a01b031684529284019290840190600101614109565b505050838103828501526141428189614061565b9150508281036040840152614157818761409a565b9050828103606084015261416b818661409a565b9050828103608084015261417f8185613fde565b98975050505050505050565b5f6020828403121561419b575f80fd5b8151613bf181613bc9565b6001600160a01b039384168152919092166020820152901515604082015260600190565b5f60208083850312156141db575f80fd5b825167ffffffffffffffff808211156141f2575f80fd5b818501915085601f830112614205575f80fd5b81518181111561421757614217613cf4565b8060051b9150614228848301613d08565b8181529183018401918481019088841115614241575f80fd5b938501935b8385101561417f57845192506001600160e01b031983168314614268575f8081fd5b8282529385019390850190614246565b80820180821115610b2c57610b2c613e66565b6001600160a01b03831681526040602080830182905283519183018290525f9184820191906060850190845b818110156142dd5784516001600160e01b031916835293830193918301916001016142b7565b5090979650505050505050565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b031685528601511515868501529284019290850190600101614306565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b0390811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0808201519086015260c0908101519085015260e09093019290850190600101614352565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080908101519085015260a090930192908501906001016143d556fe657865637574655061796c6f616428616464726573732c737472696e672c6279746573290000000000000000000000004f6f977acdd1177dcd81ab83074855ecb9c2d49ea2646970667358221220cc4fd4303a28ea03114d3976a3e0fae3acfc265462710b0fd7d5048563ccdd2064736f6c63430008150033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": { + "1617": [ + { + "length": 32, + "start": 2447 + }, + { + "length": 32, + "start": 7026 + }, + { + "length": 32, + "start": 7404 + }, + { + "length": 32, + "start": 8317 + }, + { + "length": 32, + "start": 8544 + }, + { + "length": 32, + "start": 9905 + }, + { + "length": 32, + "start": 10025 + }, + { + "length": 32, + "start": 10389 + }, + { + "length": 32, + "start": 10509 + }, + { + "length": 32, + "start": 11356 + }, + { + "length": 32, + "start": 11574 + }, + { + "length": 32, + "start": 11694 + }, + { + "length": 32, + "start": 11986 + }, + { + "length": 32, + "start": 12106 + }, + { + "length": 32, + "start": 12565 + }, + { + "length": 32, + "start": 12685 + }, + { + "length": 32, + "start": 12988 + }, + { + "length": 32, + "start": 13333 + }, + { + "length": 32, + "start": 13540 + }, + { + "length": 32, + "start": 13660 + }, + { + "length": 32, + "start": 13892 + }, + { + "length": 32, + "start": 14012 + } + ] + }, + "inputSourceName": "project/contracts/payloads/IGP126/PayloadIGP126.sol", + "buildInfoId": "solc-0_8_21-e5f103e2cd94e480aeda63ae8c9d7552dc087e58" +} \ No newline at end of file diff --git a/ignition/deployments/chain-1/build-info/solc-0_8_21-e5f103e2cd94e480aeda63ae8c9d7552dc087e58.json b/ignition/deployments/chain-1/build-info/solc-0_8_21-e5f103e2cd94e480aeda63ae8c9d7552dc087e58.json new file mode 100644 index 00000000..72f9c094 --- /dev/null +++ b/ignition/deployments/chain-1/build-info/solc-0_8_21-e5f103e2cd94e480aeda63ae8c9d7552dc087e58.json @@ -0,0 +1,114 @@ +{ + "_format": "hh3-sol-build-info-1", + "id": "solc-0_8_21-e5f103e2cd94e480aeda63ae8c9d7552dc087e58", + "solcVersion": "0.8.21", + "solcLongVersion": "0.8.21+commit.d9974bed", + "userSourceNameMap": { + "contracts/payloads/IGP126/PayloadIGP126.sol": "project/contracts/payloads/IGP126/PayloadIGP126.sol" + }, + "input": { + "language": "Solidity", + "settings": { + "evmVersion": "shanghai", + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "": [ + "ast" + ], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "remappings": [] + }, + "sources": { + "project/contracts/payloads/common/constants.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\n\nimport {BigMathMinified} from \"../libraries/bigMathMinified.sol\";\nimport {LiquidityCalcs} from \"../libraries/liquidityCalcs.sol\";\nimport {LiquiditySlotsLink} from \"../libraries/liquiditySlotsLink.sol\";\n\nimport {IGovernorBravo} from \"./interfaces/IGovernorBravo.sol\";\nimport {ITimelock} from \"./interfaces/ITimelock.sol\";\n\nimport {IFluidLiquidityAdmin} from \"./interfaces/IFluidLiquidity.sol\";\nimport {IFluidReserveContract} from \"./interfaces/IFluidReserveContract.sol\";\n\nimport {IFluidVaultFactory} from \"./interfaces/IFluidVaultFactory.sol\";\nimport {IFluidDexFactory} from \"./interfaces/IFluidDexFactory.sol\";\nimport {\n IFluidSmartLendingFactory\n} from \"./interfaces/IFluidSmartLendingFactory.sol\";\nimport {IFluidLendingFactory} from \"./interfaces/IFluidLendingFactory.sol\";\n\nimport {IFluidDex} from \"./interfaces/IFluidDex.sol\";\nimport {IFluidDexResolver} from \"./interfaces/IFluidDex.sol\";\n\nimport {IFluidVault} from \"./interfaces/IFluidVault.sol\";\nimport {IFluidVaultT1} from \"./interfaces/IFluidVault.sol\";\n\nimport {IFTokenAdmin} from \"./interfaces/IFToken.sol\";\nimport {ILendingRewards} from \"./interfaces/IFToken.sol\";\n\nimport {IDSAV2} from \"./interfaces/IDSA.sol\";\n\nimport {ILite} from \"./interfaces/ILite.sol\";\n\nimport {IDSAConnectorsV2} from \"./interfaces/IDSA.sol\";\n\ncontract PayloadIGPConstants {\n address public immutable ADDRESS_THIS;\n\n // Proposal Creators\n address public constant PROPOSER =\n 0xA45f7bD6A5Ff45D31aaCE6bCD3d426D9328cea01;\n address public constant PROPOSER_AVO_MULTISIG =\n 0x059A94A72951c0ae1cc1CE3BF0dB52421bbE8210;\n address public constant PROPOSER_AVO_MULTISIG_2 =\n 0x9efdE135CA4832AbF0408c44c6f5f370eB0f35e8;\n address public constant PROPOSER_AVO_MULTISIG_3 =\n 0x5C43AAC965ff230AC1cF63e924D0153291D78BaD;\n address public constant PROPOSER_AVO_MULTISIG_4 =\n 0x3dAff61fe5cfB1f1B4eA7FBa8173A58532Ef1841;\n address public constant PROPOSER_AVO_MULTISIG_5 =\n 0xE7EB63a8B6392481A9FDEbb108Cfd580DC8664d3;\n\n // Governance Addresses\n IGovernorBravo public constant GOVERNOR =\n IGovernorBravo(0x0204Cd037B2ec03605CFdFe482D8e257C765fA1B);\n ITimelock public constant TIMELOCK =\n ITimelock(0x2386DC45AdDed673317eF068992F19421B481F4c);\n IDSAV2 public constant TREASURY =\n IDSAV2(0x28849D2b63fA8D361e5fc15cB8aBB13019884d09);\n IDSAConnectorsV2 public constant DSA_CONNECTORS_V2 =\n IDSAConnectorsV2(0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11);\n\n // Team Multisig\n address public constant TEAM_MULTISIG =\n 0x4F6F977aCDD1177DCD81aB83074855EcB9C2D49e;\n address public constant TEAM_MULTISIG_2 =\n 0x1e2e1aeD876f67Fe4Fd54090FD7B8F57Ce234219;\n\n // Fluid Addresses\n IFluidLiquidityAdmin public constant LIQUIDITY =\n IFluidLiquidityAdmin(0x52Aa899454998Be5b000Ad077a46Bbe360F4e497);\n IFluidReserveContract public constant FLUID_RESERVE =\n IFluidReserveContract(0x264786EF916af64a1DB19F513F24a3681734ce92);\n address public constant RESERVE_CONTRACT_PROXY =\n 0x264786EF916af64a1DB19F513F24a3681734ce92;\n\n // Fluid Factory Addresses\n IFluidVaultFactory public constant VAULT_FACTORY =\n IFluidVaultFactory(0x324c5Dc1fC42c7a4D43d92df1eBA58a54d13Bf2d);\n IFluidDexFactory public constant DEX_FACTORY =\n IFluidDexFactory(0x91716C4EDA1Fb55e84Bf8b4c7085f84285c19085);\n IFluidSmartLendingFactory public constant SMART_LENDING_FACTORY =\n IFluidSmartLendingFactory(0xe57227C7d5900165344b190fc7aa580bceb53B9B);\n IFluidLendingFactory public constant LENDING_FACTORY =\n IFluidLendingFactory(0x54B91A0D94cb471F37f949c60F7Fa7935b551D03);\n\n ILite public constant IETHV2 =\n ILite(0xA0D3707c569ff8C87FA923d3823eC5D81c98Be78);\n\n // Dex V2 & Money Market Proxies (Liquidity Layer users)\n address internal constant DEX_V2_PROXY =\n 0x4E42f9e626FAcDdd97EDFA537AA52C5024448625;\n address internal constant MONEY_MARKET_PROXY =\n 0xe3B7e3f4da603FC40fD889caBdEe30a4cf15DD34;\n\n // Tokens\n address internal constant ETH_ADDRESS =\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n address internal constant WETH_ADDRESS =\n 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n address internal constant wstETH_ADDRESS =\n 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0;\n address internal constant stETH_ADDRESS =\n 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84;\n address internal constant weETH_ADDRESS =\n 0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee;\n address internal constant rsETH_ADDRESS =\n 0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7;\n address internal constant weETHs_ADDRESS =\n 0x917ceE801a67f933F2e6b33fC0cD1ED2d5909D88;\n address internal constant mETH_ADDRESS =\n 0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa;\n address internal constant ezETH_ADDRESS =\n 0xbf5495Efe5DB9ce00f80364C8B423567e58d2110;\n address internal constant OSETH_ADDRESS =\n 0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38;\n\n address internal constant USDC_ADDRESS =\n 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;\n address internal constant USDT_ADDRESS =\n 0xdAC17F958D2ee523a2206206994597C13D831ec7;\n address internal constant sUSDe_ADDRESS =\n 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497;\n address internal constant syrupUSDC_ADDRESS =\n 0x80ac24aA929eaF5013f6436cdA2a7ba190f5Cc0b;\n address internal constant syrupUSDT_ADDRESS =\n 0x356B8d89c1e1239Cbbb9dE4815c39A1474d5BA7D;\n address internal constant sUSDs_ADDRESS =\n 0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD;\n address internal constant USDe_ADDRESS =\n 0x4c9EDD5852cd905f086C759E8383e09bff1E68B3;\n address internal constant GHO_ADDRESS =\n 0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f;\n address internal constant iUSD_ADDRESS =\n 0x48f9e38f3070AD8945DFEae3FA70987722E3D89c;\n address internal constant deUSD_ADDRESS =\n 0x15700B564Ca08D9439C58cA5053166E8317aa138;\n address internal constant USR_ADDRESS =\n 0x66a1E37c9b0eAddca17d3662D6c05F4DECf3e110;\n address internal constant USD0_ADDRESS =\n 0x73A15FeD60Bf67631dC6cd7Bc5B6e8da8190aCF5;\n address internal constant fxUSD_ADDRESS =\n 0x085780639CC2cACd35E474e71f4d000e2405d8f6;\n address internal constant BOLD_ADDRESS =\n 0xb01dd87B29d187F3E3a4Bf6cdAebfb97F3D9aB98;\n address internal constant USDTb_ADDRESS =\n 0xC139190F447e929f090Edeb554D95AbB8b18aC1C;\n address internal constant csUSDL_ADDRESS =\n 0xbEeFc011e94f43b8B7b455eBaB290C7Ab4E216f1;\n address internal constant JRUSDE_ADDRESS =\n 0xC58D044404d8B14e953C115E67823784dEA53d8F;\n address internal constant SRUSDE_ADDRESS =\n 0x3d7d6fdf07EE548B939A80edbc9B2256d0cdc003;\n address internal constant REUSD_ADDRESS =\n 0x5086bf358635B81D8C47C66d1C8b9E567Db70c72;\n\n address internal constant WBTC_ADDRESS =\n 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;\n address internal constant cbBTC_ADDRESS =\n 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf;\n address internal constant tBTC_ADDRESS =\n 0x18084fbA666a33d37592fA2633fD49a74DD93a88;\n address internal constant eBTC_ADDRESS =\n 0x657e8C867D8B37dCC18fA4Caead9C45EB088C642;\n address internal constant lBTC_ADDRESS =\n 0x8236a87084f8B84306f72007F36F2618A5634494;\n\n address internal constant INST_ADDRESS =\n 0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb;\n address internal constant FLUID_ADDRESS =\n 0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb;\n\n address internal constant RLP_ADDRESS =\n 0x4956b52aE2fF65D74CA2d61207523288e4528f96;\n address internal constant wstUSR_ADDRESS =\n 0x1202F5C7b4B9E47a1A484E8B270be34dbbC75055;\n\n address internal constant XAUT_ADDRESS =\n 0x68749665FF8D2d112Fa859AA293F07A622782F38;\n address internal constant PAXG_ADDRESS =\n 0x45804880De22913dAFE09f4980848ECE6EcbAf78;\n\n // Fluid Foundation\n address internal constant FLUID_FOUNDATION =\n 0xde0377eF25aD02dBcFbc87D632E46bf1972A0Dc3;\n\n // fTokens\n address internal constant F_USDT_ADDRESS =\n 0x5C20B550819128074FD538Edf79791733ccEdd18;\n address internal constant F_USDC_ADDRESS =\n 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33;\n address internal constant F_WETH_ADDRESS =\n 0x90551c1795392094FE6D29B758EcCD233cFAa260;\n address internal constant F_WSTETH_ADDRESS =\n 0x2411802D8BEA09be0aF8fD8D08314a63e706b29C;\n address internal constant F_GHO_ADDRESS =\n 0x6A29A46E21C730DcA1d8b23d637c101cec605C5B;\n address internal constant F_SUSDs_ADDRESS =\n 0x2BBE31d63E6813E3AC858C04dae43FB2a72B0D11;\n address internal constant F_USDTb_ADDRESS =\n 0x15e8c742614b5D8Db4083A41Df1A14F5D2bFB400;\n\n // Constants\n uint256 internal constant X8 = 0xff;\n uint256 internal constant X10 = 0x3ff;\n uint256 internal constant X14 = 0x3fff;\n uint256 internal constant X15 = 0x7fff;\n uint256 internal constant X16 = 0xffff;\n uint256 internal constant X17 = 0x1ffff;\n uint256 internal constant X18 = 0x3ffff;\n uint256 internal constant X24 = 0xffffff;\n uint256 internal constant X64 = 0xffffffffffffffff;\n\n uint256 internal constant ONE_MILLION = 1_000_000;\n\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xff;\n\n constructor() {\n ADDRESS_THIS = address(this);\n }\n}\n" + }, + "project/contracts/payloads/common/helpers.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\n\nimport {BigMathMinified} from \"../libraries/bigMathMinified.sol\";\nimport {LiquidityCalcs} from \"../libraries/liquidityCalcs.sol\";\nimport {LiquiditySlotsLink} from \"../libraries/liquiditySlotsLink.sol\";\n\nimport {DexSlotsLink} from \"../libraries/dexSlotsLink.sol\";\n\nimport {IGovernorBravo} from \"./interfaces/IGovernorBravo.sol\";\nimport {ITimelock} from \"./interfaces/ITimelock.sol\";\n\nimport {IFluidLiquidityAdmin, AdminModuleStructs as FluidLiquidityAdminStructs} from \"./interfaces/IFluidLiquidity.sol\";\nimport {IFluidReserveContract} from \"./interfaces/IFluidReserveContract.sol\";\n\nimport {IFluidVaultFactory} from \"./interfaces/IFluidVaultFactory.sol\";\nimport {IFluidDexFactory} from \"./interfaces/IFluidDexFactory.sol\";\nimport {IFluidLendingFactory} from \"./interfaces/IFluidLendingFactory.sol\";\n\nimport {IFluidDex, IFluidAdminDex} from \"./interfaces/IFluidDex.sol\";\nimport {IFluidDexResolver} from \"./interfaces/IFluidDex.sol\";\n\nimport {IFluidVault} from \"./interfaces/IFluidVault.sol\";\nimport {IFluidVaultT1} from \"./interfaces/IFluidVault.sol\";\n\nimport {IFTokenAdmin} from \"./interfaces/IFToken.sol\";\nimport {ILendingRewards} from \"./interfaces/IFToken.sol\";\n\nimport {ISmartLendingAdmin} from \"./interfaces/ISmartLending.sol\";\n\nimport {IDSAV2} from \"./interfaces/IDSA.sol\";\n\nimport {PayloadIGPConstants} from \"./constants.sol\";\n\ncontract PayloadIGPHelpers is PayloadIGPConstants {\n /**\n * |\n * | Proposal Payload Helpers |\n * |__________________________________\n */\n function getVaultAddress(uint256 vaultId_) public view returns (address) {\n return VAULT_FACTORY.getVaultAddress(vaultId_);\n }\n\n function getDexAddress(uint256 dexId_) public view returns (address) {\n return DEX_FACTORY.getDexAddress(dexId_);\n }\n\n function getFTokenAddress(address token) public view returns (address) {\n if (token == WETH_ADDRESS) {\n return LENDING_FACTORY.computeToken(token, \"NativeUnderlying\");\n }\n return LENDING_FACTORY.computeToken(token, \"fToken\");\n }\n\n function getCurrentBaseWithdrawalLimit(\n address token_,\n address user_\n ) internal view returns (uint256) {\n bytes32 _LIQUDITY_PROTOCOL_SUPPLY_SLOT = LiquiditySlotsLink\n .calculateDoubleMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT,\n user_,\n token_\n );\n\n uint256 userSupplyData_ = LIQUIDITY.readFromStorage(\n _LIQUDITY_PROTOCOL_SUPPLY_SLOT\n );\n\n return\n BigMathMinified.fromBigNumber(\n (userSupplyData_ >>\n LiquiditySlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT) &\n X18,\n DEFAULT_EXPONENT_SIZE,\n DEFAULT_EXPONENT_MASK\n );\n }\n\n function setProtocolSupplyExpansion(\n address protocol,\n address token,\n uint256 expandPercent,\n uint256 expandDuration\n ) internal {\n FluidLiquidityAdminStructs.UserSupplyConfig[]\n memory configs_ = new FluidLiquidityAdminStructs.UserSupplyConfig[](\n 1\n );\n configs_[0] = FluidLiquidityAdminStructs.UserSupplyConfig({\n user: protocol,\n token: token,\n mode: 1,\n expandPercent: expandPercent,\n expandDuration: expandDuration,\n baseWithdrawalLimit: getCurrentBaseWithdrawalLimit(token, protocol) // Keep existing limit\n });\n LIQUIDITY.updateUserSupplyConfigs(configs_);\n }\n\n /// @dev gets a smart lending address based on the underlying dexId\n function getSmartLendingAddress(\n uint256 dexId_\n ) public view returns (address) {\n return SMART_LENDING_FACTORY.getSmartLendingAddress(dexId_);\n }\n\n struct SupplyProtocolConfig {\n address protocol;\n address supplyToken;\n uint256 expandPercent;\n uint256 expandDuration;\n uint256 baseWithdrawalLimitInUSD;\n }\n\n struct BorrowProtocolConfig {\n address protocol;\n address borrowToken;\n uint256 expandPercent;\n uint256 expandDuration;\n uint256 baseBorrowLimitInUSD;\n uint256 maxBorrowLimitInUSD;\n }\n\n function setSupplyProtocolLimits(\n SupplyProtocolConfig memory protocolConfig_\n ) internal {\n {\n // Supply Limits\n FluidLiquidityAdminStructs.UserSupplyConfig[]\n memory configs_ = new FluidLiquidityAdminStructs.UserSupplyConfig[](\n 1\n );\n\n configs_[0] = FluidLiquidityAdminStructs.UserSupplyConfig({\n user: address(protocolConfig_.protocol),\n token: protocolConfig_.supplyToken,\n mode: 1,\n expandPercent: protocolConfig_.expandPercent,\n expandDuration: protocolConfig_.expandDuration,\n baseWithdrawalLimit: getRawAmount(\n protocolConfig_.supplyToken,\n 0,\n protocolConfig_.baseWithdrawalLimitInUSD,\n true\n )\n });\n\n LIQUIDITY.updateUserSupplyConfigs(configs_);\n }\n }\n\n function setBorrowProtocolLimits(\n BorrowProtocolConfig memory protocolConfig_\n ) internal {\n {\n // Borrow Limits\n FluidLiquidityAdminStructs.UserBorrowConfig[]\n memory configs_ = new FluidLiquidityAdminStructs.UserBorrowConfig[](\n 1\n );\n\n configs_[0] = FluidLiquidityAdminStructs.UserBorrowConfig({\n user: address(protocolConfig_.protocol),\n token: protocolConfig_.borrowToken,\n mode: 1,\n expandPercent: protocolConfig_.expandPercent,\n expandDuration: protocolConfig_.expandDuration,\n baseDebtCeiling: getRawAmount(\n protocolConfig_.borrowToken,\n 0,\n protocolConfig_.baseBorrowLimitInUSD,\n false\n ),\n maxDebtCeiling: getRawAmount(\n protocolConfig_.borrowToken,\n 0,\n protocolConfig_.maxBorrowLimitInUSD,\n false\n )\n });\n\n LIQUIDITY.updateUserBorrowConfigs(configs_);\n }\n }\n\n function setSupplyProtocolLimitsPaused(\n address protocol_,\n address token_\n ) internal {\n {\n // Supply Limits\n FluidLiquidityAdminStructs.UserSupplyConfig[]\n memory configs_ = new FluidLiquidityAdminStructs.UserSupplyConfig[](\n 1\n );\n\n configs_[0] = FluidLiquidityAdminStructs.UserSupplyConfig({\n user: protocol_,\n token: token_,\n mode: 1,\n expandPercent: 1, // 0.01%\n expandDuration: 16777215, // max time\n baseWithdrawalLimit: 10\n });\n\n LIQUIDITY.updateUserSupplyConfigs(configs_);\n }\n }\n\n function setBorrowProtocolLimitsPaused(\n address protocol_,\n address token_\n ) internal {\n {\n // Borrow Limits\n FluidLiquidityAdminStructs.UserBorrowConfig[]\n memory configs_ = new FluidLiquidityAdminStructs.UserBorrowConfig[](\n 1\n );\n\n configs_[0] = FluidLiquidityAdminStructs.UserBorrowConfig({\n user: protocol_,\n token: token_,\n mode: 1,\n expandPercent: 1, // 0.01%\n expandDuration: 16777215, // max time\n baseDebtCeiling: 10,\n maxDebtCeiling: 20\n });\n\n LIQUIDITY.updateUserBorrowConfigs(configs_);\n }\n }\n\n function setSupplyProtocolLimitsPausedDex(\n address dex_,\n address user_\n ) internal {\n {\n // Supply Limits for DEX - using DEX-specific interface\n IFluidAdminDex.UserSupplyConfig[]\n memory configs_ = new IFluidAdminDex.UserSupplyConfig[](1);\n\n configs_[0] = IFluidAdminDex.UserSupplyConfig({\n user: user_,\n expandPercent: 1, // 0.01%\n expandDuration: 16777215, // max time\n baseWithdrawalLimit: 10 // minimal limit for pausing\n });\n\n IFluidDex(dex_).updateUserSupplyConfigs(configs_);\n }\n }\n\n function setBorrowProtocolLimitsPausedDex(\n address dex_,\n address user_\n ) internal {\n {\n // Borrow Limits for DEX - using DEX-specific interface\n IFluidAdminDex.UserBorrowConfig[]\n memory configs_ = new IFluidAdminDex.UserBorrowConfig[](1);\n\n configs_[0] = IFluidAdminDex.UserBorrowConfig({\n user: user_,\n expandPercent: 1, // 0.01%\n expandDuration: 16777215, // max time\n baseDebtCeiling: 10, // minimal limit for pausing\n maxDebtCeiling: 20 // minimal limit for pausing\n });\n\n IFluidDex(dex_).updateUserBorrowConfigs(configs_);\n }\n }\n\n struct DexBorrowProtocolConfigInShares {\n address dex;\n address protocol;\n uint256 expandPercent;\n uint256 expandDuration;\n uint256 baseBorrowLimit;\n uint256 maxBorrowLimit;\n }\n\n function setDexBorrowProtocolLimitsInShares(\n DexBorrowProtocolConfigInShares memory protocolConfig_\n ) internal {\n IFluidAdminDex.UserBorrowConfig[]\n memory config_ = new IFluidAdminDex.UserBorrowConfig[](1);\n config_[0] = IFluidAdminDex.UserBorrowConfig({\n user: protocolConfig_.protocol,\n expandPercent: protocolConfig_.expandPercent,\n expandDuration: protocolConfig_.expandDuration,\n baseDebtCeiling: protocolConfig_.baseBorrowLimit,\n maxDebtCeiling: protocolConfig_.maxBorrowLimit\n });\n\n IFluidDex(protocolConfig_.dex).updateUserBorrowConfigs(config_);\n }\n\n function getRawAmount(\n address token,\n uint256 amount,\n uint256 amountInUSD,\n bool isSupply\n ) public view virtual returns (uint256) {\n return 0;\n }\n\n struct DexConfig {\n address dex;\n address tokenA;\n address tokenB;\n bool smartCollateral;\n bool smartDebt;\n uint256 baseWithdrawalLimitInUSD;\n uint256 baseBorrowLimitInUSD;\n uint256 maxBorrowLimitInUSD;\n }\n\n enum VAULT_TYPE {\n TYPE_1,\n TYPE_2,\n TYPE_3,\n TYPE_4\n }\n\n struct VaultConfig {\n address vault;\n VAULT_TYPE vaultType;\n address supplyToken;\n address borrowToken;\n uint256 baseWithdrawalLimitInUSD;\n uint256 baseBorrowLimitInUSD;\n uint256 maxBorrowLimitInUSD;\n }\n\n function setDexLimits(DexConfig memory dex_) internal {\n // Smart Collateral\n if (dex_.smartCollateral) {\n SupplyProtocolConfig\n memory protocolConfigTokenA_ = SupplyProtocolConfig({\n protocol: dex_.dex,\n supplyToken: dex_.tokenA,\n expandPercent: 50 * 1e2, // 50%\n expandDuration: 1 hours, // 1 hour\n baseWithdrawalLimitInUSD: dex_.baseWithdrawalLimitInUSD\n });\n\n setSupplyProtocolLimits(protocolConfigTokenA_);\n\n SupplyProtocolConfig\n memory protocolConfigTokenB_ = SupplyProtocolConfig({\n protocol: dex_.dex,\n supplyToken: dex_.tokenB,\n expandPercent: 50 * 1e2, // 50%\n expandDuration: 1 hours, // 1 hour\n baseWithdrawalLimitInUSD: dex_.baseWithdrawalLimitInUSD\n });\n\n setSupplyProtocolLimits(protocolConfigTokenB_);\n }\n\n // Smart Debt\n if (dex_.smartDebt) {\n BorrowProtocolConfig\n memory protocolConfigTokenA_ = BorrowProtocolConfig({\n protocol: dex_.dex,\n borrowToken: dex_.tokenA,\n expandPercent: 50 * 1e2, // 50%\n expandDuration: 1 hours, // 1 hour\n baseBorrowLimitInUSD: dex_.baseBorrowLimitInUSD,\n maxBorrowLimitInUSD: dex_.maxBorrowLimitInUSD\n });\n\n setBorrowProtocolLimits(protocolConfigTokenA_);\n\n BorrowProtocolConfig\n memory protocolConfigTokenB_ = BorrowProtocolConfig({\n protocol: dex_.dex,\n borrowToken: dex_.tokenB,\n expandPercent: 50 * 1e2, // 50%\n expandDuration: 1 hours, // 1 hour\n baseBorrowLimitInUSD: dex_.baseBorrowLimitInUSD,\n maxBorrowLimitInUSD: dex_.maxBorrowLimitInUSD\n });\n\n setBorrowProtocolLimits(protocolConfigTokenB_);\n }\n }\n\n function setVaultLimits(VaultConfig memory vault_) internal {\n if (vault_.vaultType == VAULT_TYPE.TYPE_1) {\n SupplyProtocolConfig memory protocolConfig_ = SupplyProtocolConfig({\n protocol: vault_.vault,\n supplyToken: vault_.supplyToken,\n expandPercent: 50 * 1e2, // 50%\n expandDuration: 6 hours, // 6 hours\n baseWithdrawalLimitInUSD: vault_.baseWithdrawalLimitInUSD\n });\n\n setSupplyProtocolLimits(protocolConfig_);\n }\n\n if (vault_.vaultType == VAULT_TYPE.TYPE_1) {\n BorrowProtocolConfig memory protocolConfig_ = BorrowProtocolConfig({\n protocol: vault_.vault,\n borrowToken: vault_.borrowToken,\n expandPercent: 50 * 1e2, // 50%\n expandDuration: 6 hours, // 6 hours\n baseBorrowLimitInUSD: vault_.baseBorrowLimitInUSD,\n maxBorrowLimitInUSD: vault_.maxBorrowLimitInUSD\n });\n\n setBorrowProtocolLimits(protocolConfig_);\n }\n\n if (vault_.vaultType == VAULT_TYPE.TYPE_2) {\n BorrowProtocolConfig memory protocolConfig_ = BorrowProtocolConfig({\n protocol: vault_.vault,\n borrowToken: vault_.borrowToken,\n expandPercent: 30 * 1e2, // 30%\n expandDuration: 6 hours, // 6 hours\n baseBorrowLimitInUSD: vault_.baseBorrowLimitInUSD,\n maxBorrowLimitInUSD: vault_.maxBorrowLimitInUSD\n });\n\n setBorrowProtocolLimits(protocolConfig_);\n }\n\n if (vault_.vaultType == VAULT_TYPE.TYPE_3) {\n SupplyProtocolConfig memory protocolConfig_ = SupplyProtocolConfig({\n protocol: vault_.vault,\n supplyToken: vault_.supplyToken,\n expandPercent: 35 * 1e2, // 35%\n expandDuration: 6 hours, // 6 hours\n baseWithdrawalLimitInUSD: vault_.baseWithdrawalLimitInUSD\n });\n\n setSupplyProtocolLimits(protocolConfig_);\n }\n }\n\n function updateDexBaseLimits(\n uint256 dexId,\n uint256 maxSupplySharesInUSD,\n uint256 maxBorrowSharesInUSD\n ) internal {\n address dexAddress = getDexAddress(dexId);\n if (dexAddress == address(0)) return;\n\n (address AddressTokenA, address AddressTokenB) = getDexTokens(\n dexAddress\n );\n\n uint256 baseWithdrawalInUSD = (maxSupplySharesInUSD * 45) / 100; // 45% of supply cap\n uint256 baseBorrowInUSD = (maxBorrowSharesInUSD * 60) / 100; // 60% of max borrow cap\n uint256 maxBorrowInUSD = (maxBorrowSharesInUSD * 125) / 100; // 25% increase\n\n DexConfig memory dex_ = DexConfig({\n dex: dexAddress,\n tokenA: AddressTokenA,\n tokenB: AddressTokenB,\n smartCollateral: maxSupplySharesInUSD > 0,\n smartDebt: maxBorrowSharesInUSD > 0,\n baseWithdrawalLimitInUSD: baseWithdrawalInUSD,\n baseBorrowLimitInUSD: baseBorrowInUSD,\n maxBorrowLimitInUSD: maxBorrowInUSD\n });\n setDexLimits(dex_);\n }\n\n function getDexTokens(\n address dexAddress_\n ) internal view returns (address, address) {\n IFluidDex.ConstantViews memory constantViews_ = IFluidDex(dexAddress_)\n .constantsView();\n\n return (constantViews_.token0, constantViews_.token1);\n }\n\n function updateDexRevenueCut(uint256 dexId, uint256 revenueCut) internal {\n address dexAddress = getDexAddress(dexId);\n uint256 dexVariables2_ = IFluidDex(dexAddress).readFromStorage(\n bytes32(DexSlotsLink.DEX_VARIABLES2_SLOT)\n );\n uint256 fee_ = (dexVariables2_ >> 2) & X17;\n\n IFluidDex(dexAddress).updateFeeAndRevenueCut(\n fee_, // fee stays the same\n revenueCut\n );\n }\n}\n" + }, + "project/contracts/payloads/common/interfaces/ICodeReader.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.21;\n\ninterface ICodeReader {\n function readCode(address target) external view returns (bytes memory);\n} " + }, + "project/contracts/payloads/common/interfaces/IDSA.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IDSAV2 {\n function cast(\n string[] memory _targetNames,\n bytes[] memory _datas,\n address _origin\n )\n external\n payable \n returns (bytes32);\n\n function isAuth(address user) external view returns (bool);\n}\n\ninterface IDSAConnectorsV2 {\n function toggleChief(address _chiefAddress) external;\n}\n" + }, + "project/contracts/payloads/common/interfaces/IERC20.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IERC20 {\n function allowance(\n address spender,\n address caller\n ) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function balanceOf(address account) external view returns (uint256);\n}" + }, + "project/contracts/payloads/common/interfaces/IFluidDex.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IFluidAdminDex {\n /// @param upperThresholdPercent_ in 4 decimals, 10000 = 1%\n /// @param lowerThresholdPercent_ in 4 decimals, 10000 = 1%\n /// @param thresholdShiftTime_ in secs, in how much time the threshold percent should take to shift the ranges\n /// @param shiftTime_ in secs, in how much time the upper config changes should be fully done.\n function updateThresholdPercent(\n uint upperThresholdPercent_,\n uint lowerThresholdPercent_,\n uint thresholdShiftTime_,\n uint shiftTime_\n ) external;\n\n function updateCenterPriceLimits(\n uint maxCenterPrice_,\n uint minCenterPrice_\n ) external;\n\n function updateCenterPriceAddress(\n uint centerPriceAddress_,\n uint percent_,\n uint time_\n ) external;\n\n function readFromStorage(\n bytes32 slot_\n ) external view returns (uint256 result_);\n\n function updateMaxSupplyShares(uint maxSupplyShares_) external;\n\n function updateMaxBorrowShares(uint maxBorrowShares_) external;\n\n /// @notice struct to set user supply & withdrawal config\n struct UserSupplyConfig {\n ///\n /// @param user address\n address user;\n ///\n /// @param expandPercent withdrawal limit expand percent. in 1e2: 100% = 10_000; 1% = 100\n /// Also used to calculate rate at which withdrawal limit should decrease (instant).\n uint256 expandPercent;\n ///\n /// @param expandDuration withdrawal limit expand duration in seconds.\n /// used to calculate rate together with expandPercent\n uint256 expandDuration;\n ///\n /// @param baseWithdrawalLimit base limit, below this, user can withdraw the entire amount.\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\n /// with interest -> raw, without interest -> normal\n uint256 baseWithdrawalLimit;\n }\n\n /// @notice struct to set user borrow & payback config\n struct UserBorrowConfig {\n ///\n /// @param user address\n address user;\n ///\n /// @param expandPercent debt limit expand percent. in 1e2: 100% = 10_000; 1% = 100\n /// Also used to calculate rate at which debt limit should decrease (instant).\n uint256 expandPercent;\n ///\n /// @param expandDuration debt limit expand duration in seconds.\n /// used to calculate rate together with expandPercent\n uint256 expandDuration;\n ///\n /// @param baseDebtCeiling base borrow limit. until here, borrow limit remains as baseDebtCeiling\n /// (user can borrow until this point at once without stepped expansion). Above this, automated limit comes in place.\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\n /// with interest -> raw, without interest -> normal\n uint256 baseDebtCeiling;\n ///\n /// @param maxDebtCeiling max borrow ceiling, maximum amount the user can borrow.\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\n /// with interest -> raw, without interest -> normal\n uint256 maxDebtCeiling;\n }\n\n function updateUserBorrowConfigs(\n UserBorrowConfig[] memory userBorrowConfigs_\n ) external;\n\n function updateUserSupplyConfigs(\n UserSupplyConfig[] memory userSupplyConfigs_\n ) external;\n\n struct InitializeVariables {\n bool smartCol;\n uint token0ColAmt;\n bool smartDebt;\n uint token0DebtAmt;\n uint centerPrice;\n uint fee;\n uint revenueCut;\n uint upperPercent;\n uint lowerPercent;\n uint upperShiftThreshold;\n uint lowerShiftThreshold;\n uint thresholdShiftTime;\n uint centerPriceAddress;\n uint hookAddress;\n uint maxCenterPrice;\n uint minCenterPrice;\n }\n\n function initialize(InitializeVariables memory initializeVariables_) external payable;\n\n function updateRangePercents(\n uint upperPercent_,\n uint lowerPercent_,\n uint shiftTime_\n ) external; \n\n /// @param fee_ in 4 decimals, 10000 = 1%\n /// @param revenueCut_ in 4 decimals, 100000 = 10%, 10% cut on fee_, so if fee is 1% and cut is 10% then cut in swap amount will be 10% of 1% = 0.1%\n function updateFeeAndRevenueCut(uint fee_, uint revenueCut_) external;\n\n /// @notice pause user operations at DEX level\n /// @param user_ address of user to pause operations for\n /// @param pauseSupply_ whether to pause supply operations\n /// @param pauseBorrow_ whether to pause borrow operations\n function pauseUser(address user_, bool pauseSupply_, bool pauseBorrow_) external;\n\n function pauseSwapAndArbitrage() external;\n}\n\ninterface IFluidUserDex {\n\n\n struct Implementations {\n address shift;\n address admin;\n address colOperations;\n address debtOperations;\n address perfectOperationsAndOracle;\n }\n\n struct ConstantViews {\n uint256 dexId;\n address liquidity;\n address factory;\n Implementations implementations;\n address deployerContract;\n address token0;\n address token1;\n bytes32 supplyToken0Slot;\n bytes32 borrowToken0Slot;\n bytes32 supplyToken1Slot;\n bytes32 borrowToken1Slot;\n bytes32 exchangePriceToken0Slot;\n bytes32 exchangePriceToken1Slot;\n uint256 oracleMapping;\n }\n\n\n function constantsView() external view returns (ConstantViews memory constantsView_);\n\n}\n\ninterface IFluidDex is IFluidAdminDex, IFluidUserDex {\n}\n\ninterface IFluidDexResolver {\n struct Configs {\n bool isSmartCollateralEnabled;\n bool isSmartDebtEnabled;\n uint256 fee;\n uint256 revenueCut;\n uint256 upperRange;\n uint256 lowerRange;\n uint256 upperShiftThreshold;\n uint256 lowerShiftThreshold;\n uint256 shiftingTime;\n address centerPriceAddress;\n address hookAddress;\n uint256 maxCenterPrice;\n uint256 minCenterPrice;\n uint256 utilizationLimitToken0;\n uint256 utilizationLimitToken1;\n uint256 maxSupplyShares;\n uint256 maxBorrowShares;\n }\n\n function getDexConfigs(\n address dex_\n ) external view returns (Configs memory configs_);\n}" + }, + "project/contracts/payloads/common/interfaces/IFluidDexFactory.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IFluidDexFactory {\n /// @notice Computes the address of a dex based on its given ID (`dexId_`).\n /// @param dexId_ The ID of the dex.\n /// @return dex_ Returns the computed address of the dex.\n function getDexAddress(uint256 dexId_) external view returns (address dex_);\n\n function setDexAuth(address dex_, address dexAuth_, bool allowed_) external;\n\n /// @notice Sets an address (`globalAuth_`) as a global authorization or not.\n /// This function can only be called by the owner.\n /// @param globalAuth_ The address to be set as global authorization.\n /// @param allowed_ A boolean indicating whether the specified address is allowed to update any dex config.\n function setGlobalAuth(address globalAuth_, bool allowed_) external;\n\n /// @notice Sets an address as a factory-level authorization or not.\n /// @param auth The address to be set as factory authorization.\n /// @param allowed A boolean indicating whether the specified address is allowed as factory auth.\n function setFactoryAuth(address auth, bool allowed) external;\n\n /// @notice Sets an address as a deployer or not.\n /// @param deployer_ The address to be set as deployer.\n /// @param allowed_ A boolean indicating whether the specified address is allowed as deployer.\n function setDeployer(address deployer_, bool allowed_) external;\n\n function owner() external view returns (address);\n\n function setDexDeploymentLogic(\n address deploymentLogic_,\n bool allowed_\n ) external;\n}" + }, + "project/contracts/payloads/common/interfaces/IFluidLendingFactory.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IFluidLendingFactory {\n /// @notice Computes the address of a token based on the asset and fToken type.\n /// @param asset_ The address of the underlying asset.\n /// @param fTokenType_ The type of fToken (e.g., \"fToken\" or \"NativeUnderlying\").\n /// @return The computed address of the token.\n function computeToken(address asset_, string calldata fTokenType_) external view returns (address);\n\n /// @notice Sets an address as a factory-level authorization or not.\n /// @param auth The address to be set as factory authorization.\n /// @param allowed A boolean indicating whether the specified address is allowed as factory auth.\n function setFactoryAuth(address auth, bool allowed) external;\n\n /// @notice Sets an address as a deployer or not.\n /// @param deployer_ The address to be set as deployer.\n /// @param allowed_ A boolean indicating whether the specified address is allowed as deployer.\n function setDeployer(address deployer_, bool allowed_) external;\n}" + }, + "project/contracts/payloads/common/interfaces/IFluidLiquidity.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\n\ninterface AdminModuleStructs {\n struct AddressBool {\n address addr;\n bool value;\n }\n\n struct AddressUint256 {\n address addr;\n uint256 value;\n }\n\n struct RateDataV1Params {\n address token;\n uint256 kink;\n uint256 rateAtUtilizationZero;\n uint256 rateAtUtilizationKink;\n uint256 rateAtUtilizationMax;\n }\n\n struct RateDataV2Params {\n address token;\n uint256 kink1;\n uint256 kink2;\n uint256 rateAtUtilizationZero;\n uint256 rateAtUtilizationKink1;\n uint256 rateAtUtilizationKink2;\n uint256 rateAtUtilizationMax;\n }\n\n struct TokenConfig {\n address token;\n uint256 fee;\n uint256 threshold;\n uint256 maxUtilization;\n }\n\n struct UserSupplyConfig {\n address user;\n address token;\n uint8 mode;\n uint256 expandPercent;\n uint256 expandDuration;\n uint256 baseWithdrawalLimit;\n }\n\n struct UserBorrowConfig {\n address user;\n address token;\n uint8 mode;\n uint256 expandPercent;\n uint256 expandDuration;\n uint256 baseDebtCeiling;\n uint256 maxDebtCeiling;\n }\n}\n\ninterface IFluidLiquidityAdmin {\n /// @notice adds/removes auths. Auths generally could be contracts which can have restricted actions defined on contract.\n /// auths can be helpful in reducing governance overhead where it's not needed.\n /// @param authsStatus_ array of structs setting allowed status for an address.\n /// status true => add auth, false => remove auth\n function updateAuths(\n AdminModuleStructs.AddressBool[] calldata authsStatus_\n ) external;\n\n /// @notice adds/removes guardians. Only callable by Governance.\n /// @param guardiansStatus_ array of structs setting allowed status for an address.\n /// status true => add guardian, false => remove guardian\n function updateGuardians(\n AdminModuleStructs.AddressBool[] calldata guardiansStatus_\n ) external;\n\n /// @notice changes the revenue collector address (contract that is sent revenue). Only callable by Governance.\n /// @param revenueCollector_ new revenue collector address\n function updateRevenueCollector(address revenueCollector_) external;\n\n /// @notice changes current status, e.g. for pausing or unpausing all user operations. Only callable by Auths.\n /// @param newStatus_ new status\n /// status = 2 -> pause, status = 1 -> resume.\n function changeStatus(uint256 newStatus_) external;\n\n /// @notice update tokens rate data version 1. Only callable by Auths.\n /// @param tokensRateData_ array of RateDataV1Params with rate data to set for each token\n function updateRateDataV1s(\n AdminModuleStructs.RateDataV1Params[] calldata tokensRateData_\n ) external;\n\n /// @notice update tokens rate data version 2. Only callable by Auths.\n /// @param tokensRateData_ array of RateDataV2Params with rate data to set for each token\n function updateRateDataV2s(\n AdminModuleStructs.RateDataV2Params[] calldata tokensRateData_\n ) external;\n\n /// @notice updates token configs: fee charge on borrowers interest & storage update utilization threshold.\n /// Only callable by Auths.\n /// @param tokenConfigs_ contains token address, fee & utilization threshold\n function updateTokenConfigs(\n AdminModuleStructs.TokenConfig[] calldata tokenConfigs_\n ) external;\n\n /// @notice updates user classes: 0 is for new protocols, 1 is for established protocols.\n /// Only callable by Auths.\n /// @param userClasses_ struct array of uint256 value to assign for each user address\n function updateUserClasses(\n AdminModuleStructs.AddressUint256[] calldata userClasses_\n ) external;\n\n /// @notice sets user supply configs per token basis. Eg: with interest or interest-free and automated limits.\n /// Only callable by Auths.\n /// @param userSupplyConfigs_ struct array containing user supply config, see `UserSupplyConfig` struct for more info\n function updateUserSupplyConfigs(\n AdminModuleStructs.UserSupplyConfig[] memory userSupplyConfigs_\n ) external;\n\n /// @notice setting user borrow configs per token basis. Eg: with interest or interest-free and automated limits.\n /// Only callable by Auths.\n /// @param userBorrowConfigs_ struct array containing user borrow config, see `UserBorrowConfig` struct for more info\n function updateUserBorrowConfigs(\n AdminModuleStructs.UserBorrowConfig[] memory userBorrowConfigs_\n ) external;\n\n /// @notice pause operations for a particular user in class 0 (class 1 users can't be paused by guardians).\n /// Only callable by Guardians.\n /// @param user_ address of user to pause operations for\n /// @param supplyTokens_ token addresses to pause withdrawals for\n /// @param borrowTokens_ token addresses to pause borrowings for\n function pauseUser(\n address user_,\n address[] calldata supplyTokens_,\n address[] calldata borrowTokens_\n ) external;\n\n /// @notice unpause operations for a particular user in class 0 (class 1 users can't be paused by guardians).\n /// Only callable by Guardians.\n /// @param user_ address of user to unpause operations for\n /// @param supplyTokens_ token addresses to unpause withdrawals for\n /// @param borrowTokens_ token addresses to unpause borrowings for\n function unpauseUser(\n address user_,\n address[] calldata supplyTokens_,\n address[] calldata borrowTokens_\n ) external;\n\n /// @notice collects revenue for tokens to configured revenueCollector address.\n /// @param tokens_ array of tokens to collect revenue for\n /// @dev Note that this can revert if token balance is < revenueAmount (utilization > 100%)\n function collectRevenue(address[] calldata tokens_) external;\n\n /// @notice gets the current updated exchange prices for n tokens and updates all prices, rates related data in storage.\n /// @param tokens_ tokens to update exchange prices for\n /// @return supplyExchangePrices_ new supply rates of overall system for each token\n /// @return borrowExchangePrices_ new borrow rates of overall system for each token\n function updateExchangePrices(\n address[] calldata tokens_\n )\n external\n returns (\n uint256[] memory supplyExchangePrices_,\n uint256[] memory borrowExchangePrices_\n );\n\n function readFromStorage(\n bytes32 slot_\n ) external view returns (uint256 result_);\n}" + }, + "project/contracts/payloads/common/interfaces/IFluidReserveContract.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\n\ninterface IFluidReserveContract {\n function isRebalancer(address user) external returns (bool);\n\n function rebalanceFToken(address protocol_) external;\n\n function rebalanceVault(address protocol_) external;\n\n function transferFunds(address token_) external;\n\n function withdrawFunds(\n address[] memory tokens_,\n uint256[] memory amounts_,\n address to_\n ) external;\n\n function getProtocolTokens(address protocol_) external;\n\n function updateAuth(address auth_, bool isAuth_) external;\n\n function updateRebalancer(address rebalancer_, bool isRebalancer_) external;\n\n function approve(\n address[] memory protocols_,\n address[] memory tokens_,\n uint256[] memory amounts_\n ) external;\n\n function revoke(\n address[] memory protocols_,\n address[] memory tokens_\n ) external;\n}\n\ninterface IFluidReserveContractV2 {\n function withdrawFunds(\n address[] memory tokens_,\n uint256[] memory amounts_,\n address to_,\n string memory reason_\n ) external;\n}\n" + }, + "project/contracts/payloads/common/interfaces/IFluidSmartLendingFactory.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IFluidSmartLendingFactory {\n /// @notice Updates the authorization status of an address for a SmartLending contract. Only callable by owner.\n /// @param smartLending_ The address of the SmartLending contract.\n /// @param auth_ The address to be updated.\n /// @param allowed_ The new authorization status.\n function updateSmartLendingAuth(\n address smartLending_,\n address auth_,\n bool allowed_\n ) external;\n\n /// @notice Sets the creation code for new SmartLending contracts. Only callable by owner.\n /// @param creationCode_ New SmartLending contract creation code.\n function setSmartLendingCreationCode(bytes calldata creationCode_) external;\n\n /// @notice Computes the address of a SmartLending contract based on a given DEX ID.\n /// @param dexId_ The ID of the DEX for which the SmartLending contract address is being computed.\n /// @return The computed SmartLending contract address.\n function getSmartLendingAddress(\n uint256 dexId_\n ) external view returns (address);\n\n /// @notice Sets an address as a factory-level authorization or not.\n /// @param auth The address to be set as factory authorization.\n /// @param allowed A boolean indicating whether the specified address is allowed as factory auth.\n function setFactoryAuth(address auth, bool allowed) external;\n\n /// @notice Sets an address as a deployer or not.\n /// @param deployer_ The address to be set as deployer.\n /// @param allowed_ A boolean indicating whether the specified address is allowed as deployer.\n function updateDeployer(address deployer_, bool allowed_) external;\n}\n" + }, + "project/contracts/payloads/common/interfaces/IFluidVault.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IFluidVaultT1 {\n /// @notice updates the Vault oracle to `newOracle_`. Must implement the FluidOracle interface.\n function updateOracle(address newOracle_) external;\n\n /// @notice updates the all Vault core settings according to input params.\n /// All input values are expected in 1e2 (1% = 100, 100% = 10_000).\n function updateCoreSettings(\n uint256 supplyRateMagnifier_,\n uint256 borrowRateMagnifier_,\n uint256 collateralFactor_,\n uint256 liquidationThreshold_,\n uint256 liquidationMaxLimit_,\n uint256 withdrawGap_,\n uint256 liquidationPenalty_,\n uint256 borrowFee_\n ) external;\n\n /// @notice updates the allowed rebalancer to `newRebalancer_`.\n function updateRebalancer(address newRebalancer_) external;\n\n /// @notice updates the supply rate magnifier to `supplyRateMagnifier_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateSupplyRateMagnifier(uint supplyRateMagnifier_) external;\n\n /// @notice updates the borrow rate magnifier to `borrowRateMagnifier_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateBorrowRateMagnifier(uint borrowRateMagnifier_) external;\n\n /// @notice updates the collateral factor to `collateralFactor_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateCollateralFactor(uint collateralFactor_) external;\n\n /// @notice updates the liquidation threshold to `liquidationThreshold_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateLiquidationThreshold(uint liquidationThreshold_) external;\n\n /// @notice updates the liquidation max limit to `liquidationMaxLimit_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateLiquidationMaxLimit(uint liquidationMaxLimit_) external;\n\n /// @notice updates the withdrawal gap to `withdrawGap_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateWithdrawGap(uint withdrawGap_) external;\n\n /// @notice updates the liquidation penalty to `liquidationPenalty_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateLiquidationPenalty(uint liquidationPenalty_) external;\n\n /// @notice updates the borrow fee to `borrowFee_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateBorrowFee(uint borrowFee_) external;\n\n function readFromStorage(\n bytes32 slot_\n ) external view returns (uint256 result_);\n\n struct ConstantViews {\n address liquidity;\n address factory;\n address adminImplementation;\n address secondaryImplementation;\n address supplyToken;\n address borrowToken;\n uint8 supplyDecimals;\n uint8 borrowDecimals;\n uint vaultId;\n bytes32 liquiditySupplyExchangePriceSlot;\n bytes32 liquidityBorrowExchangePriceSlot;\n bytes32 liquidityUserSupplySlot;\n bytes32 liquidityUserBorrowSlot;\n }\n\n /// @notice returns all Vault constants\n function constantsView()\n external\n view\n returns (ConstantViews memory constantsView_);\n\n function absorbDustDebt(uint[] memory nftIds) external;\n}\n\ninterface IFluidSmartVault {\n function TYPE() external view returns (uint256);\n\n struct Tokens {\n address token0;\n address token1;\n }\n\n struct ConstantViews {\n address liquidity;\n address factory;\n address operateImplementation;\n address adminImplementation;\n address secondaryImplementation;\n address deployer; // address which deploys oracle\n address supply; // either liquidity layer or DEX protocol\n address borrow; // either liquidity layer or DEX protocol\n Tokens supplyToken; // if smart collateral then address of token0 & token1 else just supply token address at token0 and token1 as empty\n Tokens borrowToken; // if smart debt then address of token0 & token1 else just borrow token address at token0 and token1 as empty\n uint256 vaultId;\n uint256 vaultType;\n bytes32 supplyExchangePriceSlot; // if smart collateral then slot is from DEX protocol else from liquidity layer\n bytes32 borrowExchangePriceSlot; // if smart debt then slot is from DEX protocol else from liquidity layer\n bytes32 userSupplySlot; // if smart collateral then slot is from DEX protocol else from liquidity layer\n bytes32 userBorrowSlot; // if smart debt then slot is from DEX protocol else from liquidity layer\n }\n\n /// @notice returns all Vault constants\n function constantsView()\n external\n view\n returns (ConstantViews memory constantsView_);\n\n function updateOracle(uint256 newOracle_) external;\n}\n\ninterface IFluidVault {\n function updateOracle(uint256 newOracle_) external;\n}\n\ninterface IFluidVaultT2 {\n /// @notice updates the all Vault core settings according to input params.\n /// All input values are expected in 1e2 (1% = 100, 100% = 10_000).\n function updateCoreSettings(\n int256 supplyRate_,\n uint256 borrowRateMagnifier_,\n uint256 collateralFactor_,\n uint256 liquidationThreshold_,\n uint256 liquidationMaxLimit_,\n uint256 withdrawGap_,\n uint256 liquidationPenalty_,\n uint256 borrowFee_\n ) external;\n}\n" + }, + "project/contracts/payloads/common/interfaces/IFluidVaultFactory.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\ninterface IFluidVaultFactory {\n /// @notice Sets an address as allowed vault deployment logic (`deploymentLogic_`) contract or not.\n /// This function can only be called by the owner.\n /// @param deploymentLogic_ The address of the vault deployment logic contract to be set.\n /// @param allowed_ A boolean indicating whether the specified address is allowed to deploy new type of vault.\n function setVaultDeploymentLogic(\n address deploymentLogic_,\n bool allowed_\n ) external;\n\n /// @notice Sets an address (`vaultAuth_`) as allowed vault authorization or not for a specific vault (`vault_`).\n /// This function can only be called by the owner.\n /// @param vault_ The address of the vault for which the authorization is being set.\n /// @param vaultAuth_ The address to be set as vault authorization.\n /// @param allowed_ A boolean indicating whether the specified address is allowed to update the specific vault config.\n function setVaultAuth(\n address vault_,\n address vaultAuth_,\n bool allowed_\n ) external;\n\n /// @notice Computes the address of a vault based on its given ID (`vaultId_`).\n /// @param vaultId_ The ID of the vault.\n /// @return vault_ Returns the computed address of the vault.\n function getVaultAddress(\n uint256 vaultId_\n ) external view returns (address vault_);\n\n /// @notice Sets an address (`globalAuth_`) as a global authorization or not.\n /// This function can only be called by the owner.\n /// @param globalAuth_ The address to be set as global authorization.\n /// @param allowed_ A boolean indicating whether the specified address is allowed to update any vault config.\n function setGlobalAuth(address globalAuth_, bool allowed_) external;\n\n /// @notice Sets an address as a factory-level authorization or not.\n /// @param auth The address to be set as factory authorization.\n /// @param allowed A boolean indicating whether the specified address is allowed as factory auth.\n function setFactoryAuth(address auth, bool allowed) external;\n\n /// @notice Sets an address as a deployer or not.\n /// @param deployer_ The address to be set as deployer.\n /// @param allowed_ A boolean indicating whether the specified address is allowed as deployer.\n function setDeployer(address deployer_, bool allowed_) external;\n}" + }, + "project/contracts/payloads/common/interfaces/IFToken.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IFTokenAdmin {\n /// @notice updates the rewards rate model contract.\n /// Only callable by LendingFactory auths.\n /// @param rewardsRateModel_ the new rewards rate model contract address.\n /// can be set to address(0) to set no rewards (to save gas)\n function updateRewards(address rewardsRateModel_) external;\n\n /// @notice Balances out the difference between fToken supply at Liquidity vs totalAssets().\n /// Deposits underlying from rebalancer address into Liquidity but doesn't mint any shares\n /// -> thus making deposit available as rewards.\n /// Only callable by rebalancer.\n /// @return assets_ amount deposited to Liquidity\n function rebalance() external payable returns (uint256 assets_);\n\n /// @notice gets the liquidity exchange price of the underlying asset, calculates the updated exchange price (with reward rates)\n /// and writes those values to storage.\n /// Callable by anyone.\n /// @return tokenExchangePrice_ exchange price of fToken share to underlying asset\n /// @return liquidityExchangePrice_ exchange price at Liquidity for the underlying asset\n function updateRates()\n external\n returns (uint256 tokenExchangePrice_, uint256 liquidityExchangePrice_);\n\n /// @notice sends any potentially stuck funds to Liquidity contract. Only callable by LendingFactory auths.\n function rescueFunds(address token_) external;\n\n /// @notice Updates the rebalancer address (ReserveContract). Only callable by LendingFactory auths.\n function updateRebalancer(address rebalancer_) external;\n}\n\ninterface ILendingRewards {\n function start() external;\n}" + }, + "project/contracts/payloads/common/interfaces/IGovernorBravo.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\ninterface IGovernorBravo {\n function _acceptAdmin() external;\n\n function _setVotingDelay(uint256 newVotingDelay) external;\n\n function _setVotingPeriod(uint256 newVotingPeriod) external;\n\n function _acceptAdminOnTimelock() external;\n\n function _setImplementation(address implementation_) external;\n\n function propose(\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n string memory description\n ) external returns (uint256);\n\n function admin() external view returns (address);\n\n function pendingAdmin() external view returns (address);\n\n function timelock() external view returns (address);\n\n function votingDelay() external view returns (uint256);\n\n function votingPeriod() external view returns (uint256);\n}" + }, + "project/contracts/payloads/common/interfaces/IInfiniteProxy.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface IInfiniteProxy {\n function setAdmin(address newAdmin_) external;\n\n function setDummyImplementation(address newDummyImplementation_) external;\n\n function addImplementation(\n address implementation_,\n bytes4[] calldata sigs_\n ) external;\n\n function removeImplementation(address implementation_) external;\n\n function getAdmin() external view returns (address);\n\n function getDummyImplementation() external view returns (address);\n\n function getImplementationSigs(\n address impl_\n ) external view returns (bytes4[] memory);\n\n function getSigsImplementation(bytes4 sig_) external view returns (address);\n\n function readFromStorage(\n bytes32 slot_\n ) external view returns (uint256 result_);\n}\n" + }, + "project/contracts/payloads/common/interfaces/ILite.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface ILite {\n function setAdmin(address newAdmin) external;\n\n function getAdmin() external view returns (address);\n\n function removeImplementation(address implementation_) external;\n\n function addImplementation(\n address implementation_,\n bytes4[] calldata sigs_\n ) external;\n\n function setDummyImplementation(address newDummyImplementation_) external;\n\n function updateMaxRiskRatio(\n uint8[] memory protocolId_,\n uint256[] memory newRiskRatio_\n ) external;\n\n function updateAggrMaxVaultRatio(uint256 newAggrMaxVaultRatio_) external;\n\n function addDSAAuth(address auth_) external;\n \n // Collect stETH revenue to the treasury address set in Lite\n // amount_ is specified in stETH wei (1e18 per stETH)\n function collectRevenue(uint256 amount_) external;\n \n function getImplementationSigs(address implementation_) external view returns (bytes4[] memory);\n function updateSecondaryAuth(address secondaryAuth_) external;\n function updateRebalancer(address rebalancer_, bool isRebalancer_) external;\n function updateTreasury(address treasury_) external;\n}" + }, + "project/contracts/payloads/common/interfaces/ISmartLending.sol": { + "content": "pragma solidity ^0.8.21;\n\ninterface ISmartLendingAdmin {\n /// @notice set the rebalancer address (ReserveContract). Only callable by SmartLendingFactory auths.\n function setRebalancer(address rebalancer_) external;\n\n /// @dev Set the fee or reward. Only callable by auths.\n /// @param feeOrReward_ The new fee or reward (1e6 = 100%, 1e4 = 1%, minimum 0.0001% fee or reward). 0 means no fee or reward\n function setFeeOrReward(int256 feeOrReward_) external;\n}" + }, + "project/contracts/payloads/common/interfaces/ITimelock.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\n\ninterface ITimelock {\n function acceptAdmin() external;\n\n function setDelay(uint256 delay_) external;\n\n function setPendingAdmin(address pendingAdmin_) external;\n\n function queueTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) external returns (bytes32);\n\n function executeTransaction(\n address target,\n uint256 value,\n string memory signature,\n bytes memory data,\n uint256 eta\n ) external payable returns (bytes memory);\n\n function pendingAdmin() external view returns (address);\n\n function admin() external view returns (address);\n\n function delay() external view returns (uint256);\n}" + }, + "project/contracts/payloads/common/main.sol": { + "content": "pragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\n\nimport {BigMathMinified} from \"../libraries/bigMathMinified.sol\";\nimport {LiquidityCalcs} from \"../libraries/liquidityCalcs.sol\";\nimport {LiquiditySlotsLink} from \"../libraries/liquiditySlotsLink.sol\";\n\nimport { IGovernorBravo } from \"./interfaces/IGovernorBravo.sol\";\nimport { ITimelock } from \"./interfaces/ITimelock.sol\";\n\nimport { IFluidLiquidityAdmin, AdminModuleStructs as FluidLiquidityAdminStructs } from \"./interfaces/IFluidLiquidity.sol\";\nimport { IFluidReserveContract } from \"./interfaces/IFluidReserveContract.sol\";\n\nimport { IFluidVaultFactory } from \"./interfaces/IFluidVaultFactory.sol\";\nimport { IFluidDexFactory } from \"./interfaces/IFluidDexFactory.sol\";\n\nimport { IFluidDex, IFluidAdminDex } from \"./interfaces/IFluidDex.sol\";\nimport { IFluidDexResolver } from \"./interfaces/IFluidDex.sol\";\n\nimport { IFluidVault } from \"./interfaces/IFluidVault.sol\";\nimport { IFluidVaultT1 } from \"./interfaces/IFluidVault.sol\";\n\nimport { IFTokenAdmin } from \"./interfaces/IFToken.sol\";\nimport { ILendingRewards } from \"./interfaces/IFToken.sol\";\n\nimport { IDSAV2 } from \"./interfaces/IDSA.sol\";\n\nimport { PayloadIGPConstants } from \"./constants.sol\";\nimport { PayloadIGPHelpers } from \"./helpers.sol\";\n\n\nabstract contract PayloadIGPMain is PayloadIGPHelpers {\n /**\n * |\n * | State Variables |\n * |__________________________\n */\n /// @notice The unix time when the proposal was created\n uint40 internal _proposalCreationTime;\n\n /// @notice Boolean value to check if the proposal is executable. Default is not executable.\n bool internal _isProposalExecutable;\n\n /// @notice Actions that can be skipped\n mapping(uint256 => bool) internal _skipAction;\n\n /// @notice Modifier to check if an action can be skipped\n modifier isActionSkippable(uint256 action_) {\n // If function is not skippable, then execute\n if (!PayloadIGPMain(ADDRESS_THIS).actionStatus(action_)) {\n _;\n }\n }\n\n /**\n * |\n * | Team Multisig Actions |\n * |__________________________________\n */\n function setActionsToSkip(\n uint256[] calldata actionsToSkip_\n ) external {\n if (msg.sender != TEAM_MULTISIG) {\n revert(\"not-team-multisig\");\n }\n\n for (uint256 i = 0; i < actionsToSkip_.length; i++) {\n _skipAction[actionsToSkip_[i]] = true;\n }\n }\n\n // @notice Allows the team multisig to toggle the proposal executable or not\n // @param isExecutable_ The boolean value to set the proposal executable or not\n function toggleExecutable(bool isExecutable_) external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n _isProposalExecutable = isExecutable_;\n }\n\n\n /**\n * |\n * | Proposal Structure |\n * |__________________________________\n */\n\n function propose(string memory description) external {\n require(\n msg.sender == PROPOSER ||\n msg.sender == TEAM_MULTISIG ||\n address(this) == PROPOSER_AVO_MULTISIG ||\n address(this) == PROPOSER_AVO_MULTISIG_2 ||\n address(this) == PROPOSER_AVO_MULTISIG_3 ||\n address(this) == PROPOSER_AVO_MULTISIG_4 ||\n address(this) == PROPOSER_AVO_MULTISIG_5,\n \"msg.sender-not-allowed\"\n );\n\n uint256 totalActions = 1;\n address[] memory targets = new address[](totalActions);\n uint256[] memory values = new uint256[](totalActions);\n string[] memory signatures = new string[](totalActions);\n bytes[] memory calldatas = new bytes[](totalActions);\n\n targets[0] = address(TIMELOCK);\n values[0] = 0;\n signatures[0] = \"executePayload(address,string,bytes)\";\n calldatas[0] = abi.encode(ADDRESS_THIS, \"execute()\", abi.encode());\n\n uint256 proposedId = GOVERNOR.propose(\n targets,\n values,\n signatures,\n calldatas,\n description\n );\n\n require(proposedId == _PROPOSAL_ID(), \"PROPOSAL_IS_NOT_SAME\");\n\n if (msg.sender == PROPOSER || msg.sender == TEAM_MULTISIG) {\n setProposalCreationTime(uint40(block.timestamp));\n } else {\n PayloadIGPMain(ADDRESS_THIS).setProposalCreationTime(uint40(block.timestamp));\n }\n }\n\n function execute() public virtual {\n require(address(this) == address(TIMELOCK), \"not-valid-caller\");\n require(PayloadIGPMain(ADDRESS_THIS).isProposalExecutable(), \"proposal-not-executable\");\n }\n\n function verifyProposal() public view virtual {}\n\n /**\n * |\n * | Proposal Payload Helpers |\n * |__________________________________\n */\n\n function _PROPOSAL_ID() internal view virtual returns(uint256) {}\n\n function setProposalCreationTime(uint40 proposalCreationTime_) public {\n require(\n msg.sender == PROPOSER ||\n msg.sender == TEAM_MULTISIG ||\n msg.sender == PROPOSER_AVO_MULTISIG ||\n msg.sender == PROPOSER_AVO_MULTISIG_2 ||\n msg.sender == PROPOSER_AVO_MULTISIG_3 ||\n msg.sender == PROPOSER_AVO_MULTISIG_4 ||\n msg.sender == PROPOSER_AVO_MULTISIG_5,\n \"msg.sender-not-allowed\"\n );\n _proposalCreationTime = proposalCreationTime_;\n }\n\n\n function isProposalExecutable() public view returns (bool) {\n return _isProposalExecutable;\n }\n\n function getProposalCreationTime() public view returns (uint40) {\n return _proposalCreationTime;\n }\n\n function actionStatus(uint256 action_) public view returns (bool) {\n return _skipAction[action_];\n }\n}\n" + }, + "project/contracts/payloads/IGP126/PayloadIGP126.sol": { + "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.21;\npragma experimental ABIEncoderV2;\n\nimport {BigMathMinified} from \"../libraries/bigMathMinified.sol\";\nimport {LiquidityCalcs} from \"../libraries/liquidityCalcs.sol\";\nimport {LiquiditySlotsLink} from \"../libraries/liquiditySlotsLink.sol\";\n\nimport {IGovernorBravo} from \"../common/interfaces/IGovernorBravo.sol\";\nimport {ITimelock} from \"../common/interfaces/ITimelock.sol\";\n\nimport {\n IFluidLiquidityAdmin,\n AdminModuleStructs as FluidLiquidityAdminStructs\n} from \"../common/interfaces/IFluidLiquidity.sol\";\nimport {\n IFluidReserveContract\n} from \"../common/interfaces/IFluidReserveContract.sol\";\n\nimport {IFluidVaultFactory} from \"../common/interfaces/IFluidVaultFactory.sol\";\nimport {IFluidDexFactory} from \"../common/interfaces/IFluidDexFactory.sol\";\n\nimport {\n IFluidDex,\n IFluidAdminDex,\n IFluidDexResolver\n} from \"../common/interfaces/IFluidDex.sol\";\n\nimport {IFluidVault, IFluidVaultT1} from \"../common/interfaces/IFluidVault.sol\";\n\nimport {IFTokenAdmin, ILendingRewards} from \"../common/interfaces/IFToken.sol\";\n\nimport {ICodeReader} from \"../common/interfaces/ICodeReader.sol\";\nimport {IDSAV2} from \"../common/interfaces/IDSA.sol\";\nimport {IERC20} from \"../common/interfaces/IERC20.sol\";\nimport {IInfiniteProxy} from \"../common/interfaces/IInfiniteProxy.sol\";\nimport {PayloadIGPConstants} from \"../common/constants.sol\";\nimport {PayloadIGPHelpers} from \"../common/helpers.sol\";\nimport {PayloadIGPMain} from \"../common/main.sol\";\n\ninterface IFluidLiquidityRollback {\n function registerRollbackImplementation(\n address oldImplementation_,\n address newImplementation_\n ) external;\n\n function registerRollbackDummyImplementation() external;\n}\n\ninterface IOwnable {\n function transferOwnership(address newOwner) external;\n}\n\n/// @notice IGP126: Add TEAM_MULTISIG as auth on wstUSR vaults/DEXes, register & upgrade UserModule LL via RollbackModule,\n/// set LL auth for operateOnBehalfOf, set new VaultFactory owner, max-restrict borrows, pause wstUSR DEX swapAndArbitrage.\ncontract PayloadIGP126 is PayloadIGPMain {\n uint256 public constant PROPOSAL_ID = 126;\n\n address public constant OLD_USER_MODULE =\n 0x2e4015880367b7C2613Df77f816739D97A8C46aD;\n\n /// @dev IFluidLiquidityLogic.operateOnBehalfOf(address,address,int256,int256,bytes)\n bytes4 private constant OPERATE_ON_BEHALF_OF_SIG =\n bytes4(\n keccak256(\"operateOnBehalfOf(address,address,int256,int256,bytes)\")\n );\n\n // --- Configurable addresses (Team Multisig can set before execution) ---\n address public userModuleAddress = address(0);\n address public dummyImplementationAddress = address(0);\n address public onBehalfOfAuth = address(0);\n address public vaultFactoryOwner = address(0);\n address public pauseableAuth = address(0);\n address public pausableDexAuth = address(0);\n\n // --- Lock flags (once true, the corresponding address can no longer be changed) ---\n bool public userModuleAddressLocked;\n bool public dummyImplementationAddressLocked;\n bool public onBehalfOfAuthLocked;\n bool public vaultFactoryOwnerLocked;\n bool public pauseableAuthLocked;\n bool public pausableDexAuthLocked;\n\n function lockUserModuleAddress() external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n userModuleAddressLocked = true;\n }\n\n function lockDummyImplementationAddress() external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n dummyImplementationAddressLocked = true;\n }\n\n function lockOnBehalfOfAuth() external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n onBehalfOfAuthLocked = true;\n }\n\n function lockVaultFactoryOwner() external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n vaultFactoryOwnerLocked = true;\n }\n\n function lockPauseableAuth() external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n pauseableAuthLocked = true;\n }\n\n function lockPausableDexAuth() external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n pausableDexAuthLocked = true;\n }\n\n function setUserModuleAddress(address userModuleAddress_) external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n require(!userModuleAddressLocked, \"locked\");\n userModuleAddress = userModuleAddress_;\n }\n\n function setDummyImplementationAddress(\n address dummyImplementationAddress_\n ) external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n require(!dummyImplementationAddressLocked, \"locked\");\n dummyImplementationAddress = dummyImplementationAddress_;\n }\n\n function setOnBehalfOfAuth(address onBehalfOfAuth_) external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n require(!onBehalfOfAuthLocked, \"locked\");\n onBehalfOfAuth = onBehalfOfAuth_;\n }\n\n function setVaultFactoryOwner(address vaultFactoryOwner_) external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n require(!vaultFactoryOwnerLocked, \"locked\");\n vaultFactoryOwner = vaultFactoryOwner_;\n }\n\n function setPauseableAuth(address pauseableAuth_) external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n require(!pauseableAuthLocked, \"locked\");\n pauseableAuth = pauseableAuth_;\n }\n\n function setPausableDexAuth(address pausableDexAuth_) external {\n require(msg.sender == TEAM_MULTISIG, \"not-team-multisig\");\n require(!pausableDexAuthLocked, \"locked\");\n pausableDexAuth = pausableDexAuth_;\n }\n\n function execute() public virtual override {\n super.execute();\n\n // Action 1: Add TEAM_MULTISIG as auth on all wstUSR vaults and DEXes\n action1();\n\n // Action 2: Register UserModule LL upgrade on RollbackModule\n action2();\n\n // Action 3: Update UserModule LL to settable address\n action3();\n\n // Action 4: Register DummyImplementation rollback on RollbackModule\n action4();\n\n // Action 5: Update DummyImplementation on LL to settable address\n action5();\n\n // Action 6: Set a contract as auth on LL (for operateOnBehalfOf)\n action6();\n\n // Action 7: Set new owner of VaultFactory (for position transfer wrapper)\n action7();\n\n // Action 8: Set max restricted borrow limits on all wstUSR vaults\n action8();\n\n // Action 9: Pause swapAndArbitrage on all wstUSR-related DEXes\n action9();\n\n // Action 10: Set pauseableAuth as auth on LL\n action10();\n\n // Action 11: Set pausableDexAuth as globalAuth on DexFactory\n action11();\n\n }\n\n function verifyProposal() public view override {}\n\n function _PROPOSAL_ID() internal view override returns (uint256) {\n return PROPOSAL_ID;\n }\n\n /**\n * |\n * | Proposal Payload Actions |\n * |__________________________________\n */\n\n /// @notice Action 1: Add TEAM_MULTISIG as auth on all wstUSR vaults and DEXes\n function action1() internal isActionSkippable(1) {\n // wstUSR Vaults\n VAULT_FACTORY.setVaultAuth(getVaultAddress(110), TEAM_MULTISIG, true); // wstUSR / USDC\n VAULT_FACTORY.setVaultAuth(getVaultAddress(111), TEAM_MULTISIG, true); // wstUSR / USDT\n VAULT_FACTORY.setVaultAuth(getVaultAddress(112), TEAM_MULTISIG, true); // wstUSR / GHO\n // skip 113 wstUSR-USDT / USDT: already max restricted / deprecated\n VAULT_FACTORY.setVaultAuth(getVaultAddress(133), TEAM_MULTISIG, true); // wstUSR-USDC <> USDC\n VAULT_FACTORY.setVaultAuth(getVaultAddress(134), TEAM_MULTISIG, true); // wstUSR-USDC <> USDC-USDT\n VAULT_FACTORY.setVaultAuth(getVaultAddress(135), TEAM_MULTISIG, true); // wstUSR-USDC <> USDC-USDT concentrated\n // skip 142 wstUSR / USDtb: already max restricted / deprecated\n VAULT_FACTORY.setVaultAuth(getVaultAddress(143), TEAM_MULTISIG, true); // wstUSR <> USDC-USDT\n VAULT_FACTORY.setVaultAuth(getVaultAddress(144), TEAM_MULTISIG, true); // wstUSR <> USDC-USDT concentrated\n\n // wstUSR DEXes\n DEX_FACTORY.setDexAuth(getDexAddress(27), TEAM_MULTISIG, true); // wstUSR-USDC\n // skip 29 wstUSR-USDT: already max restricted / deprecated\n }\n\n /// @notice Action 2: Register UserModule LL upgrade on RollbackModule (must happen before the actual upgrade)\n function action2() internal isActionSkippable(2) {\n address newUserModule_ = PayloadIGP126(ADDRESS_THIS)\n .userModuleAddress();\n require(newUserModule_ != address(0), \"user-module-not-set\");\n\n IFluidLiquidityRollback(address(LIQUIDITY))\n .registerRollbackImplementation(OLD_USER_MODULE, newUserModule_);\n }\n\n /// @notice Action 3: Update UserModule LL to settable address\n function action3() internal isActionSkippable(3) {\n address newUserModule_ = PayloadIGP126(ADDRESS_THIS)\n .userModuleAddress();\n require(newUserModule_ != address(0), \"user-module-not-set\");\n\n bytes4[] memory baseSigs_ = IInfiniteProxy(address(LIQUIDITY))\n .getImplementationSigs(OLD_USER_MODULE);\n uint256 len = baseSigs_.length;\n bytes4[] memory sigs_ = new bytes4[](len + 1);\n for (uint256 i; i < len; ++i) {\n sigs_[i] = baseSigs_[i];\n }\n sigs_[len] = OPERATE_ON_BEHALF_OF_SIG;\n\n IInfiniteProxy(address(LIQUIDITY)).removeImplementation(\n OLD_USER_MODULE\n );\n\n IInfiniteProxy(address(LIQUIDITY)).addImplementation(\n newUserModule_,\n sigs_\n );\n }\n\n /// @notice Action 4: Register DummyImplementation rollback on RollbackModule (must happen before the actual update)\n function action4() internal isActionSkippable(4) {\n IFluidLiquidityRollback(address(LIQUIDITY))\n .registerRollbackDummyImplementation();\n }\n\n /// @notice Action 5: Update DummyImplementation on LL to settable address\n function action5() internal isActionSkippable(5) {\n address newDummyImpl_ = PayloadIGP126(ADDRESS_THIS)\n .dummyImplementationAddress();\n require(newDummyImpl_ != address(0), \"dummy-impl-not-set\");\n\n IInfiniteProxy(address(LIQUIDITY)).setDummyImplementation(\n newDummyImpl_\n );\n }\n\n /// @notice Action 6: Set a contract as auth on LL (for operateOnBehalfOf)\n function action6() internal isActionSkippable(6) {\n address authAddress_ = PayloadIGP126(ADDRESS_THIS).onBehalfOfAuth();\n require(authAddress_ != address(0), \"on-behalf-of-auth-not-set\");\n\n FluidLiquidityAdminStructs.AddressBool[]\n memory authsStatus_ = new FluidLiquidityAdminStructs.AddressBool[](\n 1\n );\n authsStatus_[0] = FluidLiquidityAdminStructs.AddressBool({\n addr: authAddress_,\n value: true\n });\n LIQUIDITY.updateAuths(authsStatus_);\n }\n\n /// @notice Action 7: Set new owner of VaultFactory (for position transfer wrapper)\n function action7() internal isActionSkippable(7) {\n address newOwner_ = PayloadIGP126(ADDRESS_THIS).vaultFactoryOwner();\n require(newOwner_ != address(0), \"vault-factory-owner-not-set\");\n\n IOwnable(address(VAULT_FACTORY)).transferOwnership(newOwner_);\n }\n\n /// @notice Action 8: Set max restricted borrow limits on all wstUSR vaults\n function action8() internal isActionSkippable(8) {\n // --- Borrow limits at Liquidity Layer (T1 and T2 vaults) ---\n\n // Vault 110: wstUSR / USDC (T1)\n setBorrowProtocolLimitsPaused(getVaultAddress(110), USDC_ADDRESS);\n\n // Vault 111: wstUSR / USDT (T1)\n setBorrowProtocolLimitsPaused(getVaultAddress(111), USDT_ADDRESS);\n\n // Vault 112: wstUSR / GHO (T1)\n setBorrowProtocolLimitsPaused(getVaultAddress(112), GHO_ADDRESS);\n\n // skip 113 wstUSR-USDT / USDT: already max restricted / deprecated\n\n // Vault 133: wstUSR-USDC <> USDC (T2)\n setBorrowProtocolLimitsPaused(getVaultAddress(133), USDC_ADDRESS);\n\n // skip 142 wstUSR / USDtb: already max restricted / deprecated\n\n // --- Borrow limits at DEX level (T3 and T4 vaults) ---\n\n address USDC_USDT_DEX = getDexAddress(2);\n address USDC_USDT_CONCENTRATED_DEX = getDexAddress(34);\n\n // Vault 134: wstUSR-USDC <> USDC-USDT (T4) — borrows from USDC-USDT DEX\n setBorrowProtocolLimitsPausedDex(USDC_USDT_DEX, getVaultAddress(134));\n\n // skip 135 wstUSR-USDC / USDC-USDT concentrated: already max restricted / deprecated\n\n // Vault 143: wstUSR <> USDC-USDT (T3) — borrows from USDC-USDT DEX\n setBorrowProtocolLimitsPausedDex(USDC_USDT_DEX, getVaultAddress(143));\n\n // Vault 144: wstUSR <> USDC-USDT concentrated (T3) — borrows from USDC-USDT concentrated DEX\n setBorrowProtocolLimitsPausedDex(\n USDC_USDT_CONCENTRATED_DEX,\n getVaultAddress(144)\n );\n }\n\n /// @notice Action 9: Pause `swapAndArbitrage` on all wstUSR-related DEXes\n function action9() internal isActionSkippable(9) {\n IFluidDex(getDexAddress(27)).pauseSwapAndArbitrage(); // wstUSR-USDC\n // skip 29 wstUSR-USDT: already max restricted / deprecated\n }\n\n /// @notice Action 10: Set pauseableAuth as auth on Liquidity Layer\n function action10() internal isActionSkippable(10) {\n address authAddress_ = PayloadIGP126(ADDRESS_THIS).pauseableAuth();\n require(authAddress_ != address(0), \"pauseable-auth-not-set\");\n\n FluidLiquidityAdminStructs.AddressBool[]\n memory authsStatus_ = new FluidLiquidityAdminStructs.AddressBool[](\n 1\n );\n authsStatus_[0] = FluidLiquidityAdminStructs.AddressBool({\n addr: authAddress_,\n value: true\n });\n LIQUIDITY.updateAuths(authsStatus_);\n }\n\n /// @notice Action 11: Set pausableDexAuth as globalAuth on DexFactory\n function action11() internal isActionSkippable(11) {\n address authAddress_ = PayloadIGP126(ADDRESS_THIS).pausableDexAuth();\n require(authAddress_ != address(0), \"pausable-dex-auth-not-set\");\n\n DEX_FACTORY.setGlobalAuth(authAddress_, true);\n }\n\n /**\n * |\n * | Payload Actions End Here |\n * |__________________________________\n */\n\n // Token Prices Constants\n uint256 public constant ETH_USD_PRICE = 2_000 * 1e2;\n uint256 public constant wstETH_USD_PRICE = 3_575 * 1e2;\n uint256 public constant weETH_USD_PRICE = 3_050 * 1e2;\n uint256 public constant rsETH_USD_PRICE = 2_980 * 1e2;\n uint256 public constant weETHs_USD_PRICE = 2_920 * 1e2;\n uint256 public constant mETH_USD_PRICE = 3_040 * 1e2;\n uint256 public constant ezETH_USD_PRICE = 3_000 * 1e2;\n uint256 public constant OSETH_USD_PRICE = 3_060 * 1e2;\n\n uint256 public constant BTC_USD_PRICE = 69_000 * 1e2;\n\n uint256 public constant STABLE_USD_PRICE = 1 * 1e2;\n uint256 public constant sUSDe_USD_PRICE = 1.20 * 1e2;\n uint256 public constant sUSDs_USD_PRICE = 1.08 * 1e2;\n uint256 public constant syrupUSDT_USD_PRICE = 1.10 * 1e2;\n uint256 public constant syrupUSDC_USD_PRICE = 1.14 * 1e2;\n uint256 public constant REUSD_USD_PRICE = 1.06 * 1e2;\n uint256 public constant csUSDL_USD_PRICE = 1.03 * 1e2;\n\n uint256 public constant FLUID_USD_PRICE = 2.19 * 1e2;\n\n uint256 public constant RLP_USD_PRICE = 1.26 * 1e2;\n uint256 public constant wstUSR_USD_PRICE = 1.12 * 1e2;\n uint256 public constant XAUT_USD_PRICE = 4_040 * 1e2;\n uint256 public constant PAXG_USD_PRICE = 4_050 * 1e2;\n uint256 public constant JRUSDE_USD_PRICE = 1.00 * 1e2;\n uint256 public constant SRUSDE_USD_PRICE = 1.00 * 1e2;\n\n function getRawAmount(\n address token,\n uint256 amount,\n uint256 amountInUSD,\n bool isSupply\n ) public view override returns (uint256) {\n if (amount > 0 && amountInUSD > 0) {\n revert(\"both usd and amount are not zero\");\n }\n uint256 exchangePriceAndConfig_ = LIQUIDITY.readFromStorage(\n LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n token\n )\n );\n\n (\n uint256 supplyExchangePrice,\n uint256 borrowExchangePrice\n ) = LiquidityCalcs.calcExchangePrices(exchangePriceAndConfig_);\n\n uint256 usdPrice = 0;\n uint256 decimals = 18;\n if (token == ETH_ADDRESS) {\n usdPrice = ETH_USD_PRICE;\n decimals = 18;\n } else if (token == wstETH_ADDRESS) {\n usdPrice = wstETH_USD_PRICE;\n decimals = 18;\n } else if (token == weETH_ADDRESS) {\n usdPrice = weETH_USD_PRICE;\n decimals = 18;\n } else if (token == rsETH_ADDRESS) {\n usdPrice = rsETH_USD_PRICE;\n decimals = 18;\n } else if (token == weETHs_ADDRESS) {\n usdPrice = weETHs_USD_PRICE;\n decimals = 18;\n } else if (token == mETH_ADDRESS) {\n usdPrice = mETH_USD_PRICE;\n decimals = 18;\n } else if (token == ezETH_ADDRESS) {\n usdPrice = ezETH_USD_PRICE;\n decimals = 18;\n } else if (token == OSETH_ADDRESS) {\n usdPrice = OSETH_USD_PRICE;\n decimals = 18;\n } else if (\n token == cbBTC_ADDRESS ||\n token == WBTC_ADDRESS ||\n token == eBTC_ADDRESS ||\n token == lBTC_ADDRESS\n ) {\n usdPrice = BTC_USD_PRICE;\n decimals = 8;\n } else if (token == tBTC_ADDRESS) {\n usdPrice = BTC_USD_PRICE;\n decimals = 18;\n } else if (token == USDC_ADDRESS || token == USDT_ADDRESS) {\n usdPrice = STABLE_USD_PRICE;\n decimals = 6;\n } else if (token == sUSDe_ADDRESS) {\n usdPrice = sUSDe_USD_PRICE;\n decimals = 18;\n } else if (token == sUSDs_ADDRESS) {\n usdPrice = sUSDs_USD_PRICE;\n decimals = 18;\n } else if (token == syrupUSDT_ADDRESS) {\n usdPrice = syrupUSDT_USD_PRICE;\n decimals = 6;\n } else if (token == syrupUSDC_ADDRESS) {\n usdPrice = syrupUSDC_USD_PRICE;\n decimals = 6;\n } else if (token == REUSD_ADDRESS) {\n usdPrice = REUSD_USD_PRICE;\n decimals = 18;\n } else if (token == csUSDL_ADDRESS) {\n usdPrice = csUSDL_USD_PRICE;\n decimals = 18;\n } else if (token == JRUSDE_ADDRESS) {\n usdPrice = JRUSDE_USD_PRICE;\n decimals = 18;\n } else if (token == SRUSDE_ADDRESS) {\n usdPrice = SRUSDE_USD_PRICE;\n decimals = 18;\n } else if (\n token == GHO_ADDRESS ||\n token == USDe_ADDRESS ||\n token == deUSD_ADDRESS ||\n token == USR_ADDRESS ||\n token == USD0_ADDRESS ||\n token == fxUSD_ADDRESS ||\n token == BOLD_ADDRESS ||\n token == iUSD_ADDRESS ||\n token == USDTb_ADDRESS\n ) {\n usdPrice = STABLE_USD_PRICE;\n decimals = 18;\n } else if (token == INST_ADDRESS) {\n usdPrice = FLUID_USD_PRICE;\n decimals = 18;\n } else if (token == wstUSR_ADDRESS) {\n usdPrice = wstUSR_USD_PRICE;\n decimals = 18;\n } else if (token == RLP_ADDRESS) {\n usdPrice = RLP_USD_PRICE;\n decimals = 18;\n } else if (token == XAUT_ADDRESS) {\n usdPrice = XAUT_USD_PRICE;\n decimals = 6;\n } else if (token == PAXG_ADDRESS) {\n usdPrice = PAXG_USD_PRICE;\n decimals = 18;\n } else {\n revert(\"not-found\");\n }\n\n uint256 exchangePrice = isSupply\n ? supplyExchangePrice\n : borrowExchangePrice;\n\n if (amount > 0) {\n return (amount * 1e12) / exchangePrice;\n } else {\n return\n (amountInUSD * 1e12 * (10 ** decimals)) /\n ((usdPrice * exchangePrice) / 1e2);\n }\n }\n}\n" + }, + "project/contracts/payloads/libraries/bigMathMinified.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @title library that represents a number in BigNumber(coefficient and exponent) format to store in smaller bits.\n/// @notice the number is divided into two parts: a coefficient and an exponent. This comes at a cost of losing some precision\n/// at the end of the number because the exponent simply fills it with zeroes. This precision is oftentimes negligible and can\n/// result in significant gas cost reduction due to storage space reduction.\n/// Also note, a valid big number is as follows: if the exponent is > 0, then coefficient last bits should be occupied to have max precision.\n/// @dev roundUp is more like a increase 1, which happens everytime for the same number.\n/// roundDown simply sets trailing digits after coefficientSize to zero (floor), only once for the same number.\nlibrary BigMathMinified {\n /// @dev constants to use for `roundUp` input param to increase readability\n bool internal constant ROUND_DOWN = false;\n bool internal constant ROUND_UP = true;\n\n /// @dev converts `normal` number to BigNumber with `exponent` and `coefficient` (or precision).\n /// e.g.:\n /// 5035703444687813576399599 (normal) = (coefficient[32bits], exponent[8bits])[40bits]\n /// 5035703444687813576399599 (decimal) => 10000101010010110100000011111011110010100110100000000011100101001101001101011101111 (binary)\n /// => 10000101010010110100000011111011000000000000000000000000000000000000000000000000000\n /// ^-------------------- 51(exponent) -------------- ^\n /// coefficient = 1000,0101,0100,1011,0100,0000,1111,1011 (2236301563)\n /// exponent = 0011,0011 (51)\n /// bigNumber = 1000,0101,0100,1011,0100,0000,1111,1011,0011,0011 (572493200179)\n ///\n /// @param normal number which needs to be converted into Big Number\n /// @param coefficientSize at max how many bits of precision there should be (64 = uint64 (64 bits precision))\n /// @param exponentSize at max how many bits of exponent there should be (8 = uint8 (8 bits exponent))\n /// @param roundUp signals if result should be rounded down or up\n /// @return bigNumber converted bigNumber (coefficient << exponent)\n function toBigNumber(\n uint256 normal,\n uint256 coefficientSize,\n uint256 exponentSize,\n bool roundUp\n ) internal pure returns (uint256 bigNumber) {\n assembly {\n let lastBit_\n let number_ := normal\n if gt(number_, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n number_ := shr(0x80, number_)\n lastBit_ := 0x80\n }\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\n number_ := shr(0x40, number_)\n lastBit_ := add(lastBit_, 0x40)\n }\n if gt(number_, 0xFFFFFFFF) {\n number_ := shr(0x20, number_)\n lastBit_ := add(lastBit_, 0x20)\n }\n if gt(number_, 0xFFFF) {\n number_ := shr(0x10, number_)\n lastBit_ := add(lastBit_, 0x10)\n }\n if gt(number_, 0xFF) {\n number_ := shr(0x8, number_)\n lastBit_ := add(lastBit_, 0x8)\n }\n if gt(number_, 0xF) {\n number_ := shr(0x4, number_)\n lastBit_ := add(lastBit_, 0x4)\n }\n if gt(number_, 0x3) {\n number_ := shr(0x2, number_)\n lastBit_ := add(lastBit_, 0x2)\n }\n if gt(number_, 0x1) {\n lastBit_ := add(lastBit_, 1)\n }\n if gt(number_, 0) {\n lastBit_ := add(lastBit_, 1)\n }\n if lt(lastBit_, coefficientSize) {\n // for throw exception\n lastBit_ := coefficientSize\n }\n let exponent := sub(lastBit_, coefficientSize)\n let coefficient := shr(exponent, normal)\n if and(roundUp, gt(exponent, 0)) {\n // rounding up is only needed if exponent is > 0, as otherwise the coefficient fully holds the original number\n coefficient := add(coefficient, 1)\n if eq(shl(coefficientSize, 1), coefficient) {\n // case were coefficient was e.g. 111, with adding 1 it became 1000 (in binary) and coefficientSize 3 bits\n // final coefficient would exceed it's size. -> reduce coefficent to 100 and increase exponent by 1.\n coefficient := shl(sub(coefficientSize, 1), 1)\n exponent := add(exponent, 1)\n }\n }\n if iszero(lt(exponent, shl(exponentSize, 1))) {\n // if exponent is >= exponentSize, the normal number is too big to fit within\n // BigNumber with too small sizes for coefficient and exponent\n revert(0, 0)\n }\n bigNumber := shl(exponentSize, coefficient)\n bigNumber := add(bigNumber, exponent)\n }\n }\n\n /// @dev get `normal` number from `bigNumber`, `exponentSize` and `exponentMask`\n function fromBigNumber(\n uint256 bigNumber,\n uint256 exponentSize,\n uint256 exponentMask\n ) internal pure returns (uint256 normal) {\n assembly {\n let coefficient := shr(exponentSize, bigNumber)\n let exponent := and(bigNumber, exponentMask)\n normal := shl(exponent, coefficient)\n }\n }\n\n /// @dev gets the most significant bit `lastBit` of a `normal` number (length of given number of binary format).\n /// e.g.\n /// 5035703444687813576399599 = 10000101010010110100000011111011110010100110100000000011100101001101001101011101111\n /// lastBit = ^--------------------------------- 83 ----------------------------------------^\n function mostSignificantBit(uint256 normal) internal pure returns (uint lastBit) {\n assembly {\n let number_ := normal\n if gt(normal, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n number_ := shr(0x80, number_)\n lastBit := 0x80\n }\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\n number_ := shr(0x40, number_)\n lastBit := add(lastBit, 0x40)\n }\n if gt(number_, 0xFFFFFFFF) {\n number_ := shr(0x20, number_)\n lastBit := add(lastBit, 0x20)\n }\n if gt(number_, 0xFFFF) {\n number_ := shr(0x10, number_)\n lastBit := add(lastBit, 0x10)\n }\n if gt(number_, 0xFF) {\n number_ := shr(0x8, number_)\n lastBit := add(lastBit, 0x8)\n }\n if gt(number_, 0xF) {\n number_ := shr(0x4, number_)\n lastBit := add(lastBit, 0x4)\n }\n if gt(number_, 0x3) {\n number_ := shr(0x2, number_)\n lastBit := add(lastBit, 0x2)\n }\n if gt(number_, 0x1) {\n lastBit := add(lastBit, 1)\n }\n if gt(number_, 0) {\n lastBit := add(lastBit, 1)\n }\n }\n }\n}" + }, + "project/contracts/payloads/libraries/dexSlotsLink.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @notice library that helps in reading / working with storage slot data of Fluid Dex.\n/// @dev as all data for Fluid Dex is internal, any data must be fetched directly through manual\n/// slot reading through this library or, if gas usage is less important, through the FluidDexResolver.\nlibrary DexSlotsLink {\n /// @dev storage slot for variables at Dex\n uint256 internal constant DEX_VARIABLES_SLOT = 0;\n /// @dev storage slot for variables2 at Dex\n uint256 internal constant DEX_VARIABLES2_SLOT = 1;\n /// @dev storage slot for total supply shares at Dex\n uint256 internal constant DEX_TOTAL_SUPPLY_SHARES_SLOT = 2;\n /// @dev storage slot for user supply mapping at Dex\n uint256 internal constant DEX_USER_SUPPLY_MAPPING_SLOT = 3;\n /// @dev storage slot for total borrow shares at Dex\n uint256 internal constant DEX_TOTAL_BORROW_SHARES_SLOT = 4;\n /// @dev storage slot for user borrow mapping at Dex\n uint256 internal constant DEX_USER_BORROW_MAPPING_SLOT = 5;\n /// @dev storage slot for oracle mapping at Dex\n uint256 internal constant DEX_ORACLE_MAPPING_SLOT = 6;\n /// @dev storage slot for range and threshold shifts at Dex\n uint256 internal constant DEX_RANGE_THRESHOLD_SHIFTS_SLOT = 7;\n /// @dev storage slot for center price shift at Dex\n uint256 internal constant DEX_CENTER_PRICE_SHIFT_SLOT = 8;\n\n // --------------------------------\n // @dev stacked uint256 storage slots bits position data for each:\n\n // UserSupplyData\n uint256 internal constant BITS_USER_SUPPLY_ALLOWED = 0;\n uint256 internal constant BITS_USER_SUPPLY_AMOUNT = 1;\n uint256 internal constant BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT = 65;\n uint256 internal constant BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP = 129;\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_PERCENT = 162;\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_DURATION = 176;\n uint256 internal constant BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT = 200;\n\n // UserBorrowData\n uint256 internal constant BITS_USER_BORROW_ALLOWED = 0;\n uint256 internal constant BITS_USER_BORROW_AMOUNT = 1;\n uint256 internal constant BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT = 65;\n uint256 internal constant BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP = 129;\n uint256 internal constant BITS_USER_BORROW_EXPAND_PERCENT = 162;\n uint256 internal constant BITS_USER_BORROW_EXPAND_DURATION = 176;\n uint256 internal constant BITS_USER_BORROW_BASE_BORROW_LIMIT = 200;\n uint256 internal constant BITS_USER_BORROW_MAX_BORROW_LIMIT = 218;\n\n // --------------------------------\n\n /// @notice Calculating the slot ID for Dex contract for single mapping at `slot_` for `key_`\n function calculateMappingStorageSlot(uint256 slot_, address key_) internal pure returns (bytes32) {\n return keccak256(abi.encode(key_, slot_));\n }\n\n /// @notice Calculating the slot ID for Dex contract for double mapping at `slot_` for `key1_` and `key2_`\n function calculateDoubleMappingStorageSlot(\n uint256 slot_,\n address key1_,\n address key2_\n ) internal pure returns (bytes32) {\n bytes32 intermediateSlot_ = keccak256(abi.encode(key1_, slot_));\n return keccak256(abi.encode(key2_, intermediateSlot_));\n }\n}" + }, + "project/contracts/payloads/libraries/errorTypes.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary LibsErrorTypes {\n /***********************************|\n | LiquidityCalcs | \n |__________________________________*/\n\n /// @notice thrown when supply or borrow exchange price is zero at calc token data (token not configured yet)\n uint256 internal constant LiquidityCalcs__ExchangePriceZero = 70001;\n\n /// @notice thrown when rate data is set to a version that is not implemented\n uint256 internal constant LiquidityCalcs__UnsupportedRateVersion = 70002;\n\n /// @notice thrown when the calculated borrow rate turns negative. This should never happen.\n uint256 internal constant LiquidityCalcs__BorrowRateNegative = 70003;\n\n /***********************************|\n | SafeTransfer | \n |__________________________________*/\n\n /// @notice thrown when safe transfer from for an ERC20 fails\n uint256 internal constant SafeTransfer__TransferFromFailed = 71001;\n\n /// @notice thrown when safe transfer for an ERC20 fails\n uint256 internal constant SafeTransfer__TransferFailed = 71002;\n}" + }, + "project/contracts/payloads/libraries/liquidityCalcs.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { LibsErrorTypes as ErrorTypes } from \"./errorTypes.sol\";\nimport { LiquiditySlotsLink } from \"./liquiditySlotsLink.sol\";\nimport { BigMathMinified } from \"./bigMathMinified.sol\";\n\n/// @notice implements calculation methods used for Fluid liquidity such as updated exchange prices,\n/// borrow rate, withdrawal / borrow limits, revenue amount.\nlibrary LiquidityCalcs {\n error FluidLiquidityCalcsError(uint256 errorId_);\n\n /// @notice emitted if the calculated borrow rate surpassed max borrow rate (16 bits) and was capped at maximum value 65535\n event BorrowRateMaxCap();\n\n /// @dev constants as from Liquidity variables.sol\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n\n /// @dev Ignoring leap years\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\n // constants used for BigMath conversion from and to storage\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;\n\n uint256 internal constant FOUR_DECIMALS = 1e4;\n uint256 internal constant TWELVE_DECIMALS = 1e12;\n uint256 internal constant X14 = 0x3fff;\n uint256 internal constant X15 = 0x7fff;\n uint256 internal constant X16 = 0xffff;\n uint256 internal constant X18 = 0x3ffff;\n uint256 internal constant X24 = 0xffffff;\n uint256 internal constant X33 = 0x1ffffffff;\n uint256 internal constant X64 = 0xffffffffffffffff;\n\n ///////////////////////////////////////////////////////////////////////////\n ////////// CALC EXCHANGE PRICES /////////\n ///////////////////////////////////////////////////////////////////////////\n\n /// @dev calculates interest (exchange prices) for a token given its' exchangePricesAndConfig from storage.\n /// @param exchangePricesAndConfig_ exchange prices and config packed uint256 read from storage\n /// @return supplyExchangePrice_ updated supplyExchangePrice\n /// @return borrowExchangePrice_ updated borrowExchangePrice\n function calcExchangePrices(\n uint256 exchangePricesAndConfig_\n ) internal view returns (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) {\n // Extracting exchange prices\n supplyExchangePrice_ =\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) &\n X64;\n borrowExchangePrice_ =\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE) &\n X64;\n\n if (supplyExchangePrice_ == 0 || borrowExchangePrice_ == 0) {\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__ExchangePriceZero);\n }\n\n uint256 temp_ = exchangePricesAndConfig_ & X16; // temp_ = borrowRate\n\n unchecked {\n // last timestamp can not be > current timestamp\n uint256 secondsSinceLastUpdate_ = block.timestamp -\n ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_LAST_TIMESTAMP) & X33);\n\n uint256 borrowRatio_ = (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_RATIO) &\n X15;\n if (secondsSinceLastUpdate_ == 0 || temp_ == 0 || borrowRatio_ == 1) {\n // if no time passed, borrow rate is 0, or no raw borrowings: no exchange price update needed\n // (if borrowRatio_ == 1 means there is only borrowInterestFree, as first bit is 1 and rest is 0)\n return (supplyExchangePrice_, borrowExchangePrice_);\n }\n\n // calculate new borrow exchange price.\n // formula borrowExchangePriceIncrease: previous price * borrow rate * secondsSinceLastUpdate_.\n // nominator is max uint112 (uint64 * uint16 * uint32). Divisor can not be 0.\n borrowExchangePrice_ +=\n (borrowExchangePrice_ * temp_ * secondsSinceLastUpdate_) /\n (SECONDS_PER_YEAR * FOUR_DECIMALS);\n\n // FOR SUPPLY EXCHANGE PRICE:\n // all yield paid by borrowers (in mode with interest) goes to suppliers in mode with interest.\n // formula: previous price * supply rate * secondsSinceLastUpdate_.\n // where supply rate = (borrow rate - revenueFee%) * ratioSupplyYield. And\n // ratioSupplyYield = utilization * supplyRatio * borrowRatio\n //\n // Example:\n // supplyRawInterest is 80, supplyInterestFree is 20. totalSupply is 100. BorrowedRawInterest is 50.\n // BorrowInterestFree is 10. TotalBorrow is 60. borrow rate 40%, revenueFee 10%.\n // yield is 10 (so half a year must have passed).\n // supplyRawInterest must become worth 89. totalSupply must become 109. BorrowedRawInterest must become 60.\n // borrowInterestFree must still be 10. supplyInterestFree still 20. totalBorrow 70.\n // supplyExchangePrice would have to go from 1 to 1,125 (+ 0.125). borrowExchangePrice from 1 to 1,2 (+0.2).\n // utilization is 60%. supplyRatio = 20 / 80 = 25% (only 80% of lenders receiving yield).\n // borrowRatio = 10 / 50 = 20% (only 83,333% of borrowers paying yield):\n // x of borrowers paying yield = 100% - (20 / (100 + 20)) = 100% - 16.6666666% = 83,333%.\n // ratioSupplyYield = 60% * 83,33333% * (100% + 20%) = 62,5%\n // supplyRate = (40% * (100% - 10%)) * = 36% * 62,5% = 22.5%\n // increase in supplyExchangePrice, assuming 100 as previous price.\n // 100 * 22,5% * 1/2 (half a year) = 0,1125.\n // cross-check supplyRawInterest worth = 80 * 1.1125 = 89. totalSupply worth = 89 + 20.\n\n // -------------- 1. calculate ratioSupplyYield --------------------------------\n // step1: utilization * supplyRatio (or actually part of lenders receiving yield)\n\n // temp_ => supplyRatio (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\n // if first bit 0 then ratio is supplyInterestFree / supplyWithInterest (supplyWithInterest is bigger)\n // else ratio is supplyWithInterest / supplyInterestFree (supplyInterestFree is bigger)\n temp_ = (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_RATIO) & X15;\n\n if (temp_ == 1) {\n // if no raw supply: no exchange price update needed\n // (if supplyRatio_ == 1 means there is only supplyInterestFree, as first bit is 1 and rest is 0)\n return (supplyExchangePrice_, borrowExchangePrice_);\n }\n\n // ratioSupplyYield precision is 1e27 as 100% for increased precision when supplyInterestFree > supplyWithInterest\n if (temp_ & 1 == 1) {\n // ratio is supplyWithInterest / supplyInterestFree (supplyInterestFree is bigger)\n temp_ = temp_ >> 1;\n\n // Note: case where temp_ == 0 (only supplyInterestFree, no yield) already covered by early return\n // in the if statement a little above.\n\n // based on above example but supplyRawInterest is 20, supplyInterestFree is 80. no fee.\n // supplyRawInterest must become worth 30. totalSupply must become 110.\n // supplyExchangePrice would have to go from 1 to 1,5. borrowExchangePrice from 1 to 1,2.\n // so ratioSupplyYield must come out as 2.5 (250%).\n // supplyRatio would be (20 * 10_000 / 80) = 2500. but must be inverted.\n temp_ = (1e27 * FOUR_DECIMALS) / temp_; // e.g. 1e31 / 2500 = 4e27. (* 1e27 for precision)\n // e.g. 5_000 * (1e27 + 4e27) / 1e27 = 25_000 (=250%).\n temp_ =\n // utilization * (100% + 100% / supplyRatio)\n (((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) & X14) *\n (1e27 + temp_)) / // extract utilization (max 16_383 so there is no way this can overflow).\n (FOUR_DECIMALS);\n // max possible value of temp_ here is 16383 * (1e27 + 1e31) / 1e4 = ~1.64e31\n } else {\n // ratio is supplyInterestFree / supplyWithInterest (supplyWithInterest is bigger)\n temp_ = temp_ >> 1;\n // if temp_ == 0 then only supplyWithInterest => full yield. temp_ is already 0\n\n // e.g. 5_000 * 10_000 + (20 * 10_000 / 80) / 10_000 = 5000 * 12500 / 10000 = 6250 (=62.5%).\n temp_ =\n // 1e27 * utilization * (100% + supplyRatio) / 100%\n (1e27 *\n ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) & X14) * // extract utilization (max 16_383 so there is no way this can overflow).\n (FOUR_DECIMALS + temp_)) /\n (FOUR_DECIMALS * FOUR_DECIMALS);\n // max possible temp_ value: 1e27 * 16383 * 2e4 / 1e8 = 3.2766e27\n }\n // from here temp_ => ratioSupplyYield (utilization * supplyRatio part) scaled by 1e27. max possible value ~1.64e31\n\n // step2 of ratioSupplyYield: add borrowRatio (only x% of borrowers paying yield)\n if (borrowRatio_ & 1 == 1) {\n // ratio is borrowWithInterest / borrowInterestFree (borrowInterestFree is bigger)\n borrowRatio_ = borrowRatio_ >> 1;\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\n\n // Note: case where borrowRatio_ == 0 (only borrowInterestFree, no yield) already covered\n // at the beginning of the method by early return if `borrowRatio_ == 1`.\n\n // based on above example but borrowRawInterest is 10, borrowInterestFree is 50. no fee. borrowRatio = 20%.\n // so only 16.66% of borrowers are paying yield. so the 100% - part of the formula is not needed.\n // x of borrowers paying yield = (borrowRatio / (100 + borrowRatio)) = 16.6666666%\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\n borrowRatio_ = (borrowRatio_ * 1e27) / (FOUR_DECIMALS + borrowRatio_);\n // max value here for borrowRatio_ is (1e31 / (1e4 + 1e4))= 5e26 (= 50% of borrowers paying yield).\n } else {\n // ratio is borrowInterestFree / borrowWithInterest (borrowWithInterest is bigger)\n borrowRatio_ = borrowRatio_ >> 1;\n\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\n // x of borrowers paying yield = 100% - (borrowRatio / (100 + borrowRatio)) = 100% - 16.6666666% = 83,333%.\n borrowRatio_ = (1e27 - ((borrowRatio_ * 1e27) / (FOUR_DECIMALS + borrowRatio_)));\n // borrowRatio can never be > 100%. so max subtraction can be 100% - 100% / 200%.\n // or if borrowRatio_ is 0 -> 100% - 0. or if borrowRatio_ is 1 -> 100% - 1 / 101.\n // max value here for borrowRatio_ is 1e27 - 0 = 1e27 (= 100% of borrowers paying yield).\n }\n\n // temp_ => ratioSupplyYield. scaled down from 1e25 = 1% each to normal percent precision 1e2 = 1%.\n // max nominator value is ~1.64e31 * 1e27 = 1.64e58. max result = 1.64e8\n temp_ = (FOUR_DECIMALS * temp_ * borrowRatio_) / 1e54;\n\n // 2. calculate supply rate\n // temp_ => supply rate (borrow rate - revenueFee%) * ratioSupplyYield.\n // division part is done in next step to increase precision. (divided by 2x FOUR_DECIMALS, fee + borrowRate)\n // Note that all calculation divisions for supplyExchangePrice are rounded down.\n // Note supply rate can be bigger than the borrowRate, e.g. if there are only few lenders with interest\n // but more suppliers not earning interest.\n temp_ = ((exchangePricesAndConfig_ & X16) * // borrow rate\n temp_ * // ratioSupplyYield\n (FOUR_DECIMALS - ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_FEE) & X14))); // revenueFee\n // fee can not be > 100%. max possible = 65535 * ~1.64e8 * 1e4 =~1.074774e17.\n\n // 3. calculate increase in supply exchange price\n supplyExchangePrice_ += ((supplyExchangePrice_ * temp_ * secondsSinceLastUpdate_) /\n (SECONDS_PER_YEAR * FOUR_DECIMALS * FOUR_DECIMALS * FOUR_DECIMALS));\n // max possible nominator = max uint 64 * 1.074774e17 * max uint32 = ~8.52e45. Denominator can not be 0.\n }\n }\n\n ///////////////////////////////////////////////////////////////////////////\n ////////// CALC REVENUE /////////\n ///////////////////////////////////////////////////////////////////////////\n\n /// @dev gets the `revenueAmount_` for a token given its' totalAmounts and exchangePricesAndConfig from storage\n /// and the current balance of the Fluid liquidity contract for the token.\n /// @param totalAmounts_ total amounts packed uint256 read from storage\n /// @param exchangePricesAndConfig_ exchange prices and config packed uint256 read from storage\n /// @param liquidityTokenBalance_ current balance of Liquidity contract (IERC20(token_).balanceOf(address(this)))\n /// @return revenueAmount_ collectable revenue amount\n function calcRevenue(\n uint256 totalAmounts_,\n uint256 exchangePricesAndConfig_,\n uint256 liquidityTokenBalance_\n ) internal view returns (uint256 revenueAmount_) {\n // @dev no need to super-optimize this method as it is only used by admin\n\n // calculate the new exchange prices based on earned interest\n (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) = calcExchangePrices(exchangePricesAndConfig_);\n\n // total supply = interest free + with interest converted from raw\n uint256 totalSupply_ = getTotalSupply(totalAmounts_, supplyExchangePrice_);\n\n if (totalSupply_ > 0) {\n // available revenue: balanceOf(token) + totalBorrowings - totalLendings.\n revenueAmount_ = liquidityTokenBalance_ + getTotalBorrow(totalAmounts_, borrowExchangePrice_);\n // ensure there is no possible case because of rounding etc. where this would revert,\n // explicitly check if >\n revenueAmount_ = revenueAmount_ > totalSupply_ ? revenueAmount_ - totalSupply_ : 0;\n // Note: if utilization > 100% (totalSupply < totalBorrow), then all the amount above 100% utilization\n // can only be revenue.\n } else {\n // if supply is 0, then rest of balance can be withdrawn as revenue so that no amounts get stuck\n revenueAmount_ = liquidityTokenBalance_;\n }\n }\n\n ///////////////////////////////////////////////////////////////////////////\n ////////// CALC LIMITS /////////\n ///////////////////////////////////////////////////////////////////////////\n\n /// @dev calculates withdrawal limit before an operate execution:\n /// amount of user supply that must stay supplied (not amount that can be withdrawn).\n /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M\n /// @param userSupplyData_ user supply data packed uint256 from storage\n /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and converted from BigMath\n /// @return currentWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction.\n /// returned value is in raw for with interest mode, normal amount for interest free mode!\n function calcWithdrawalLimitBeforeOperate(\n uint256 userSupplyData_,\n uint256 userSupply_\n ) internal view returns (uint256 currentWithdrawalLimit_) {\n // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet).\n // first tx where timestamp is 0 will enter `if (lastWithdrawalLimit_ == 0)` because lastWithdrawalLimit_ is not set yet.\n // returning max withdrawal allowed, which is not exactly right but doesn't matter because the first interaction must be\n // a deposit anyway. Important is that it would not revert.\n\n // Note the first time a deposit brings the user supply amount to above the base withdrawal limit, the active limit\n // is the fully expanded limit immediately.\n\n // extract last set withdrawal limit\n uint256 lastWithdrawalLimit_ = (userSupplyData_ >>\n LiquiditySlotsLink.BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT) & X64;\n lastWithdrawalLimit_ =\n (lastWithdrawalLimit_ >> DEFAULT_EXPONENT_SIZE) <<\n (lastWithdrawalLimit_ & DEFAULT_EXPONENT_MASK);\n if (lastWithdrawalLimit_ == 0) {\n // withdrawal limit is not activated. Max withdrawal allowed\n return 0;\n }\n\n uint256 maxWithdrawableLimit_;\n uint256 temp_;\n unchecked {\n // extract max withdrawable percent of user supply and\n // calculate maximum withdrawable amount expandPercentage of user supply at full expansion duration elapsed\n // e.g.: if 10% expandPercentage, meaning 10% is withdrawable after full expandDuration has elapsed.\n\n // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\n maxWithdrawableLimit_ =\n (((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14) * userSupply_) /\n FOUR_DECIMALS;\n\n // time elapsed since last withdrawal limit was set (in seconds)\n // @dev last process timestamp is guaranteed to exist for withdrawal, as a supply must have happened before.\n // last timestamp can not be > current timestamp\n temp_ =\n block.timestamp -\n ((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP) & X33);\n }\n // calculate withdrawable amount of expandPercent that is elapsed of expandDuration.\n // e.g. if 60% of expandDuration has elapsed, then user should be able to withdraw 6% of user supply, down to 94%.\n // Note: no explicit check for this needed, it is covered by setting minWithdrawalLimit_ if needed.\n temp_ =\n (maxWithdrawableLimit_ * temp_) /\n // extract expand duration: After this, decrement won't happen (user can withdraw 100% of withdraw limit)\n ((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_DURATION) & X24); // expand duration can never be 0\n // calculate expanded withdrawal limit: last withdrawal limit - withdrawable amount.\n // Note: withdrawable amount here can grow bigger than userSupply if timeElapsed is a lot bigger than expandDuration,\n // which would cause the subtraction `lastWithdrawalLimit_ - withdrawableAmount_` to revert. In that case, set 0\n // which will cause minimum (fully expanded) withdrawal limit to be set in lines below.\n unchecked {\n // underflow explicitly checked & handled\n currentWithdrawalLimit_ = lastWithdrawalLimit_ > temp_ ? lastWithdrawalLimit_ - temp_ : 0;\n // calculate minimum withdrawal limit: minimum amount of user supply that must stay supplied at full expansion.\n // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_\n temp_ = userSupply_ - maxWithdrawableLimit_;\n }\n // if withdrawal limit is decreased below minimum then set minimum\n // (e.g. when more than expandDuration time has elapsed)\n if (temp_ > currentWithdrawalLimit_) {\n currentWithdrawalLimit_ = temp_;\n }\n }\n\n /// @dev calculates withdrawal limit after an operate execution:\n /// amount of user supply that must stay supplied (not amount that can be withdrawn).\n /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M\n /// @param userSupplyData_ user supply data packed uint256 from storage\n /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and added / subtracted with the executed operate amount\n /// @param newWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction, result from `calcWithdrawalLimitBeforeOperate`\n /// @return withdrawalLimit_ updated withdrawal limit that should be written to storage. returned value is in\n /// raw for with interest mode, normal amount for interest free mode!\n function calcWithdrawalLimitAfterOperate(\n uint256 userSupplyData_,\n uint256 userSupply_,\n uint256 newWithdrawalLimit_\n ) internal pure returns (uint256) {\n // temp_ => base withdrawal limit. below this, maximum withdrawals are allowed\n uint256 temp_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT) & X18;\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\n\n // if user supply is below base limit then max withdrawals are allowed\n if (userSupply_ < temp_) {\n return 0;\n }\n // temp_ => withdrawal limit expandPercent (is in 1e2 decimals)\n temp_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14;\n unchecked {\n // temp_ => minimum withdrawal limit: userSupply - max withdrawable limit (userSupply * expandPercent))\n // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\n // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_\n temp_ = userSupply_ - ((userSupply_ * temp_) / FOUR_DECIMALS);\n }\n // if new (before operation) withdrawal limit is less than minimum limit then set minimum limit.\n // e.g. can happen on new deposits. withdrawal limit is instantly fully expanded in a scenario where\n // increased deposit amount outpaces withrawals.\n if (temp_ > newWithdrawalLimit_) {\n return temp_;\n }\n return newWithdrawalLimit_;\n }\n\n /// @dev calculates borrow limit before an operate execution:\n /// total amount user borrow can reach (not borrowable amount in current operation).\n /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M\n /// @param userBorrowData_ user borrow data packed uint256 from storage\n /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_`\n /// @return currentBorrowLimit_ current borrow limit updated for expansion since last interaction. returned value is in\n /// raw for with interest mode, normal amount for interest free mode!\n function calcBorrowLimitBeforeOperate(\n uint256 userBorrowData_,\n uint256 userBorrow_\n ) internal view returns (uint256 currentBorrowLimit_) {\n // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet) -> base limit.\n // first tx where timestamp is 0 will enter `if (maxExpandedBorrowLimit_ < baseBorrowLimit_)` because `userBorrow_` and thus\n // `maxExpansionLimit_` and thus `maxExpandedBorrowLimit_` is 0 and `baseBorrowLimit_` can not be 0.\n\n // temp_ = extract borrow expand percent (is in 1e2 decimals)\n uint256 temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14;\n\n uint256 maxExpansionLimit_;\n uint256 maxExpandedBorrowLimit_;\n unchecked {\n // calculate max expansion limit: Max amount limit can expand to since last interaction\n // userBorrow_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\n maxExpansionLimit_ = ((userBorrow_ * temp_) / FOUR_DECIMALS);\n\n // calculate max borrow limit: Max point limit can increase to since last interaction\n maxExpandedBorrowLimit_ = userBorrow_ + maxExpansionLimit_;\n }\n\n // currentBorrowLimit_ = extract base borrow limit\n currentBorrowLimit_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;\n currentBorrowLimit_ =\n (currentBorrowLimit_ >> DEFAULT_EXPONENT_SIZE) <<\n (currentBorrowLimit_ & DEFAULT_EXPONENT_MASK);\n\n if (maxExpandedBorrowLimit_ < currentBorrowLimit_) {\n return currentBorrowLimit_;\n }\n // time elapsed since last borrow limit was set (in seconds)\n unchecked {\n // temp_ = timeElapsed_ (last timestamp can not be > current timestamp)\n temp_ =\n block.timestamp -\n ((userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP) & X33); // extract last update timestamp\n }\n\n // currentBorrowLimit_ = expandedBorrowableAmount + extract last set borrow limit\n currentBorrowLimit_ =\n // calculate borrow limit expansion since last interaction for `expandPercent` that is elapsed of `expandDuration`.\n // divisor is extract expand duration (after this, full expansion to expandPercentage happened).\n ((maxExpansionLimit_ * temp_) /\n ((userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_DURATION) & X24)) + // expand duration can never be 0\n // extract last set borrow limit\n BigMathMinified.fromBigNumber(\n (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT) & X64,\n DEFAULT_EXPONENT_SIZE,\n DEFAULT_EXPONENT_MASK\n );\n\n // if timeElapsed is bigger than expandDuration, new borrow limit would be > max expansion,\n // so set to `maxExpandedBorrowLimit_` in that case.\n // also covers the case where last process timestamp = 0 (timeElapsed would simply be very big)\n if (currentBorrowLimit_ > maxExpandedBorrowLimit_) {\n currentBorrowLimit_ = maxExpandedBorrowLimit_;\n }\n // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\n\n if (currentBorrowLimit_ > temp_) {\n currentBorrowLimit_ = temp_;\n }\n }\n\n /// @dev calculates borrow limit after an operate execution:\n /// total amount user borrow can reach (not borrowable amount in current operation).\n /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M\n /// @param userBorrowData_ user borrow data packed uint256 from storage\n /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_` and added / subtracted with the executed operate amount\n /// @param newBorrowLimit_ current borrow limit updated for expansion since last interaction, result from `calcBorrowLimitBeforeOperate`\n /// @return borrowLimit_ updated borrow limit that should be written to storage.\n /// returned value is in raw for with interest mode, normal amount for interest free mode!\n function calcBorrowLimitAfterOperate(\n uint256 userBorrowData_,\n uint256 userBorrow_,\n uint256 newBorrowLimit_\n ) internal pure returns (uint256 borrowLimit_) {\n // temp_ = extract borrow expand percent\n uint256 temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14; // (is in 1e2 decimals)\n\n unchecked {\n // borrowLimit_ = calculate maximum borrow limit at full expansion.\n // userBorrow_ needs to be at least 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\n borrowLimit_ = userBorrow_ + ((userBorrow_ * temp_) / FOUR_DECIMALS);\n }\n\n // temp_ = extract base borrow limit\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\n\n if (borrowLimit_ < temp_) {\n // below base limit, borrow limit is always base limit\n return temp_;\n }\n // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\n\n // make sure fully expanded borrow limit is not above hard max borrow limit\n if (borrowLimit_ > temp_) {\n borrowLimit_ = temp_;\n }\n // if new borrow limit (from before operate) is > max borrow limit, set max borrow limit.\n // (e.g. on a repay shrinking instantly to fully expanded borrow limit from new borrow amount. shrinking is instant)\n if (newBorrowLimit_ > borrowLimit_) {\n return borrowLimit_;\n }\n return newBorrowLimit_;\n }\n\n ///////////////////////////////////////////////////////////////////////////\n ////////// CALC RATES /////////\n ///////////////////////////////////////////////////////////////////////////\n\n /// @dev Calculates new borrow rate from utilization for a token\n /// @param rateData_ rate data packed uint256 from storage for the token\n /// @param utilization_ totalBorrow / totalSupply. 1e4 = 100% utilization\n /// @return rate_ rate for that particular token in 1e2 precision (e.g. 5% rate = 500)\n function calcBorrowRateFromUtilization(uint256 rateData_, uint256 utilization_) internal returns (uint256 rate_) {\n // extract rate version: 4 bits (0xF) starting from bit 0\n uint256 rateVersion_ = (rateData_ & 0xF);\n\n if (rateVersion_ == 1) {\n rate_ = calcRateV1(rateData_, utilization_);\n } else if (rateVersion_ == 2) {\n rate_ = calcRateV2(rateData_, utilization_);\n } else {\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__UnsupportedRateVersion);\n }\n\n if (rate_ > X16) {\n // hard cap for borrow rate at maximum value 16 bits (65535) to make sure it does not overflow storage space.\n // this is unlikely to ever happen if configs stay within expected levels.\n rate_ = X16;\n // emit event to more easily become aware\n emit BorrowRateMaxCap();\n }\n }\n\n /// @dev calculates the borrow rate based on utilization for rate data version 1 (with one kink) in 1e2 precision\n /// @param rateData_ rate data packed uint256 from storage for the token\n /// @param utilization_ in 1e2 (100% = 1e4)\n /// @return rate_ rate in 1e2 precision\n function calcRateV1(uint256 rateData_, uint256 utilization_) internal pure returns (uint256 rate_) {\n /// For rate v1 (one kink) ------------------------------------------------------\n /// Next 16 bits => 4 - 19 => Rate at utilization 0% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 20- 35 => Utilization at kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 36- 51 => Rate at utilization kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 52- 67 => Rate at utilization 100% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Last 188 bits => 68-255 => blank, might come in use in future\n\n // y = mx + c.\n // y is borrow rate\n // x is utilization\n // m = slope (m can also be negative for declining rates)\n // c is constant (c can be negative)\n\n uint256 y1_;\n uint256 y2_;\n uint256 x1_;\n uint256 x2_;\n\n // extract kink1: 16 bits (0xFFFF) starting from bit 20\n // kink is in 1e2, same as utilization, so no conversion needed for direct comparison of the two\n uint256 kink1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_UTILIZATION_AT_KINK) & X16;\n if (utilization_ < kink1_) {\n // if utilization is less than kink\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO) & X16;\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK) & X16;\n x1_ = 0; // 0%\n x2_ = kink1_;\n } else {\n // else utilization is greater than kink\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK) & X16;\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX) & X16;\n x1_ = kink1_;\n x2_ = FOUR_DECIMALS; // 100%\n }\n\n int256 constant_;\n int256 slope_;\n unchecked {\n // calculating slope with twelve decimal precision. m = (y2 - y1) / (x2 - x1).\n // utilization of x2 can not be <= utilization of x1 (so no underflow or 0 divisor)\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\n slope_ = (int256(y2_ - y1_) * int256(TWELVE_DECIMALS)) / int256((x2_ - x1_));\n\n // calculating constant at 12 decimal precision. slope is already in 12 decimal hence only multiple with y1. c = y - mx.\n // maximum y1_ value is 65535. 65535 * 1e12 can not overflow int256\n // maximum slope is 65535 - 0 * TWELVE_DECIMALS / 1 = 65535 * 1e12;\n // maximum x1_ is 100% (9_999 actually) => slope_ * x1_ can not overflow int256\n // subtraction most extreme case would be 0 - max value slope_ * x1_ => can not underflow int256\n constant_ = int256(y1_ * TWELVE_DECIMALS) - (slope_ * int256(x1_));\n\n // calculating new borrow rate\n // - slope_ max value is 65535 * 1e12,\n // - utilization max value is let's say 500% (extreme case where borrow rate increases borrow amount without new supply)\n // - constant max value is 65535 * 1e12\n // so max values are 65535 * 1e12 * 50_000 + 65535 * 1e12 -> 3.2768*10^21, which easily fits int256\n // divisor TWELVE_DECIMALS can not be 0\n slope_ = (slope_ * int256(utilization_)) + constant_; // reusing `slope_` as variable for gas savings\n if (slope_ < 0) {\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__BorrowRateNegative);\n }\n rate_ = uint256(slope_) / TWELVE_DECIMALS;\n }\n }\n\n /// @dev calculates the borrow rate based on utilization for rate data version 2 (with two kinks) in 1e4 precision\n /// @param rateData_ rate data packed uint256 from storage for the token\n /// @param utilization_ in 1e2 (100% = 1e4)\n /// @return rate_ rate in 1e4 precision\n function calcRateV2(uint256 rateData_, uint256 utilization_) internal pure returns (uint256 rate_) {\n /// For rate v2 (two kinks) -----------------------------------------------------\n /// Next 16 bits => 4 - 19 => Rate at utilization 0% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 20- 35 => Utilization at kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 36- 51 => Rate at utilization kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 52- 67 => Utilization at kink2 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 68- 83 => Rate at utilization kink2 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 16 bits => 84- 99 => Rate at utilization 100% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Last 156 bits => 100-255 => blank, might come in use in future\n\n // y = mx + c.\n // y is borrow rate\n // x is utilization\n // m = slope (m can also be negative for declining rates)\n // c is constant (c can be negative)\n\n uint256 y1_;\n uint256 y2_;\n uint256 x1_;\n uint256 x2_;\n\n // extract kink1: 16 bits (0xFFFF) starting from bit 20\n // kink is in 1e2, same as utilization, so no conversion needed for direct comparison of the two\n uint256 kink1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1) & X16;\n if (utilization_ < kink1_) {\n // if utilization is less than kink1\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO) & X16;\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1) & X16;\n x1_ = 0; // 0%\n x2_ = kink1_;\n } else {\n // extract kink2: 16 bits (0xFFFF) starting from bit 52\n uint256 kink2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2) & X16;\n if (utilization_ < kink2_) {\n // if utilization is less than kink2\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1) & X16;\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2) & X16;\n x1_ = kink1_;\n x2_ = kink2_;\n } else {\n // else utilization is greater than kink2\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2) & X16;\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX) & X16;\n x1_ = kink2_;\n x2_ = FOUR_DECIMALS;\n }\n }\n\n int256 constant_;\n int256 slope_;\n unchecked {\n // calculating slope with twelve decimal precision. m = (y2 - y1) / (x2 - x1).\n // utilization of x2 can not be <= utilization of x1 (so no underflow or 0 divisor)\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\n slope_ = (int256(y2_ - y1_) * int256(TWELVE_DECIMALS)) / int256((x2_ - x1_));\n\n // calculating constant at 12 decimal precision. slope is already in 12 decimal hence only multiple with y1. c = y - mx.\n // maximum y1_ value is 65535. 65535 * 1e12 can not overflow int256\n // maximum slope is 65535 - 0 * TWELVE_DECIMALS / 1 = 65535 * 1e12;\n // maximum x1_ is 100% (9_999 actually) => slope_ * x1_ can not overflow int256\n // subtraction most extreme case would be 0 - max value slope_ * x1_ => can not underflow int256\n constant_ = int256(y1_ * TWELVE_DECIMALS) - (slope_ * int256(x1_));\n\n // calculating new borrow rate\n // - slope_ max value is 65535 * 1e12,\n // - utilization max value is let's say 500% (extreme case where borrow rate increases borrow amount without new supply)\n // - constant max value is 65535 * 1e12\n // so max values are 65535 * 1e12 * 50_000 + 65535 * 1e12 -> 3.2768*10^21, which easily fits int256\n // divisor TWELVE_DECIMALS can not be 0\n slope_ = (slope_ * int256(utilization_)) + constant_; // reusing `slope_` as variable for gas savings\n if (slope_ < 0) {\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__BorrowRateNegative);\n }\n rate_ = uint256(slope_) / TWELVE_DECIMALS;\n }\n }\n\n /// @dev reads the total supply out of Liquidity packed storage `totalAmounts_` for `supplyExchangePrice_`\n function getTotalSupply(\n uint256 totalAmounts_,\n uint256 supplyExchangePrice_\n ) internal pure returns (uint256 totalSupply_) {\n // totalSupply_ => supplyInterestFree\n totalSupply_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE) & X64;\n totalSupply_ = (totalSupply_ >> DEFAULT_EXPONENT_SIZE) << (totalSupply_ & DEFAULT_EXPONENT_MASK);\n\n uint256 totalSupplyRaw_ = totalAmounts_ & X64; // no shifting as supplyRaw is first 64 bits\n totalSupplyRaw_ = (totalSupplyRaw_ >> DEFAULT_EXPONENT_SIZE) << (totalSupplyRaw_ & DEFAULT_EXPONENT_MASK);\n\n // totalSupply = supplyInterestFree + supplyRawInterest normalized from raw\n totalSupply_ += ((totalSupplyRaw_ * supplyExchangePrice_) / EXCHANGE_PRICES_PRECISION);\n }\n\n /// @dev reads the total borrow out of Liquidity packed storage `totalAmounts_` for `borrowExchangePrice_`\n function getTotalBorrow(\n uint256 totalAmounts_,\n uint256 borrowExchangePrice_\n ) internal pure returns (uint256 totalBorrow_) {\n // totalBorrow_ => borrowInterestFree\n // no & mask needed for borrow interest free as it occupies the last bits in the storage slot\n totalBorrow_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE);\n totalBorrow_ = (totalBorrow_ >> DEFAULT_EXPONENT_SIZE) << (totalBorrow_ & DEFAULT_EXPONENT_MASK);\n\n uint256 totalBorrowRaw_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST) & X64;\n totalBorrowRaw_ = (totalBorrowRaw_ >> DEFAULT_EXPONENT_SIZE) << (totalBorrowRaw_ & DEFAULT_EXPONENT_MASK);\n\n // totalBorrow = borrowInterestFree + borrowRawInterest normalized from raw\n totalBorrow_ += ((totalBorrowRaw_ * borrowExchangePrice_) / EXCHANGE_PRICES_PRECISION);\n }\n}" + }, + "project/contracts/payloads/libraries/liquiditySlotsLink.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @notice library that helps in reading / working with storage slot data of Fluid Liquidity.\n/// @dev as all data for Fluid Liquidity is internal, any data must be fetched directly through manual\n/// slot reading through this library or, if gas usage is less important, through the FluidLiquidityResolver.\nlibrary LiquiditySlotsLink {\n /// @dev storage slot for status at Liquidity\n uint256 internal constant LIQUIDITY_STATUS_SLOT = 1;\n /// @dev storage slot for auths mapping at Liquidity\n uint256 internal constant LIQUIDITY_AUTHS_MAPPING_SLOT = 2;\n /// @dev storage slot for guardians mapping at Liquidity\n uint256 internal constant LIQUIDITY_GUARDIANS_MAPPING_SLOT = 3;\n /// @dev storage slot for user class mapping at Liquidity\n uint256 internal constant LIQUIDITY_USER_CLASS_MAPPING_SLOT = 4;\n /// @dev storage slot for exchangePricesAndConfig mapping at Liquidity\n uint256 internal constant LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT = 5;\n /// @dev storage slot for rateData mapping at Liquidity\n uint256 internal constant LIQUIDITY_RATE_DATA_MAPPING_SLOT = 6;\n /// @dev storage slot for totalAmounts mapping at Liquidity\n uint256 internal constant LIQUIDITY_TOTAL_AMOUNTS_MAPPING_SLOT = 7;\n /// @dev storage slot for user supply double mapping at Liquidity\n uint256 internal constant LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT = 8;\n /// @dev storage slot for user borrow double mapping at Liquidity\n uint256 internal constant LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT = 9;\n /// @dev storage slot for listed tokens array at Liquidity\n uint256 internal constant LIQUIDITY_LISTED_TOKENS_ARRAY_SLOT = 10;\n\n // --------------------------------\n // @dev stacked uint256 storage slots bits position data for each:\n\n // ExchangePricesAndConfig\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATE = 0;\n uint256 internal constant BITS_EXCHANGE_PRICES_FEE = 16;\n uint256 internal constant BITS_EXCHANGE_PRICES_UTILIZATION = 30;\n uint256 internal constant BITS_EXCHANGE_PRICES_UPDATE_THRESHOLD = 44;\n uint256 internal constant BITS_EXCHANGE_PRICES_LAST_TIMESTAMP = 58;\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE = 91;\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE = 155;\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_RATIO = 219;\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATIO = 234;\n\n // RateData:\n uint256 internal constant BITS_RATE_DATA_VERSION = 0;\n // RateData: V1\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO = 4;\n uint256 internal constant BITS_RATE_DATA_V1_UTILIZATION_AT_KINK = 20;\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK = 36;\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX = 52;\n // RateData: V2\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO = 4;\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1 = 20;\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1 = 36;\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2 = 52;\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2 = 68;\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX = 84;\n\n // TotalAmounts\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_WITH_INTEREST = 0;\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE = 64;\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST = 128;\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE = 192;\n\n // UserSupplyData\n uint256 internal constant BITS_USER_SUPPLY_MODE = 0;\n uint256 internal constant BITS_USER_SUPPLY_AMOUNT = 1;\n uint256 internal constant BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT = 65;\n uint256 internal constant BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP = 129;\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_PERCENT = 162;\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_DURATION = 176;\n uint256 internal constant BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT = 200;\n uint256 internal constant BITS_USER_SUPPLY_IS_PAUSED = 255;\n\n // UserBorrowData\n uint256 internal constant BITS_USER_BORROW_MODE = 0;\n uint256 internal constant BITS_USER_BORROW_AMOUNT = 1;\n uint256 internal constant BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT = 65;\n uint256 internal constant BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP = 129;\n uint256 internal constant BITS_USER_BORROW_EXPAND_PERCENT = 162;\n uint256 internal constant BITS_USER_BORROW_EXPAND_DURATION = 176;\n uint256 internal constant BITS_USER_BORROW_BASE_BORROW_LIMIT = 200;\n uint256 internal constant BITS_USER_BORROW_MAX_BORROW_LIMIT = 218;\n uint256 internal constant BITS_USER_BORROW_IS_PAUSED = 255;\n\n // --------------------------------\n\n /// @notice Calculating the slot ID for Liquidity contract for single mapping at `slot_` for `key_`\n function calculateMappingStorageSlot(uint256 slot_, address key_) internal pure returns (bytes32) {\n return keccak256(abi.encode(key_, slot_));\n }\n\n /// @notice Calculating the slot ID for Liquidity contract for double mapping at `slot_` for `key1_` and `key2_`\n function calculateDoubleMappingStorageSlot(\n uint256 slot_,\n address key1_,\n address key2_\n ) internal pure returns (bytes32) {\n bytes32 intermediateSlot_ = keccak256(abi.encode(key1_, slot_));\n return keccak256(abi.encode(key2_, intermediateSlot_));\n }\n}\n" + } + } + } +} \ No newline at end of file diff --git a/ignition/deployments/chain-1/journal.jsonl b/ignition/deployments/chain-1/journal.jsonl index ec600c68..1cfe0811 100644 --- a/ignition/deployments/chain-1/journal.jsonl +++ b/ignition/deployments/chain-1/journal.jsonl @@ -104,3 +104,10 @@ {"futureId":"PayloadModule#PayloadIGP124","networkInteractionId":1,"nonce":368,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"99281225"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"15"}},"hash":"0xb955badf5503c917edb0052224f5cbcf4b793211ff075f28efad577baa61248a"},"type":"TRANSACTION_SEND"} {"futureId":"PayloadModule#PayloadIGP124","hash":"0xb955badf5503c917edb0052224f5cbcf4b793211ff075f28efad577baa61248a","networkInteractionId":1,"receipt":{"blockHash":"0x65e9e9ab8fcce7d01c46b2b153b066c011afc78b328658555acef9128fbaa918","blockNumber":24656374,"contractAddress":"0x28806bFD9E367B990b72E7477FCeaE3F6A6De3D8","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} {"futureId":"PayloadModule#PayloadIGP124","result":{"address":"0x28806bFD9E367B990b72E7477FCeaE3F6A6De3D8","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} + +{"artifactId":"PayloadModule#PayloadIGP126","constructorArgs":[],"contractName":"PayloadIGP126","dependencies":[],"from":"0xf6839085f692bde6a8062573e3da35e7e947c21e","futureId":"PayloadModule#PayloadIGP126","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} +{"futureId":"PayloadModule#PayloadIGP126","networkInteraction":{"data":"0x60a0604052600280546001600160a01b0319908116909155600380548216905560048054821690556005805482169055600680548216905560078054909116905534801561004b575f80fd5b503060805260805161449c6100fb5f395f818161098f01528181611b7201528181611cec0152818161207d01528181612160015281816126b101528181612729015281816128950152818161290d01528181612c5c01528181612d3601528181612dae01528181612ed201528181612f4a015281816131150152818161318d015281816132bc01528181613415015281816134e40152818161355c0152818161364401526136bc015261449c5ff3fe608060405234801561000f575f80fd5b506004361061049a575f3560e01c8063798d5ba311610263578063a90558361161014b578063c60dc265116100ca578063f53eddcc1161008f578063f53eddcc146109df578063f6370aa9146109fa578063f858b9b814610a04578063f88ed60c14610a18578063fb0ae91814610a33578063fcee0c9814610a46575f80fd5b8063c60dc26514610977578063cc025f7c1461098a578063d5818ec7146109b1578063e6bd26a2146109b9578063ed3660c5146109cc575f80fd5b8063b788f3a111610110578063b788f3a114610922578063bc3301a814610936578063bd8e486514610940578063bffa7f0f14610954578063c38b0f661461096f575f80fd5b8063a9055836146108ff578063aa98df3914610907578063ae68032b1461091a578063b6966495146106df578063b753428b146104c3575f80fd5b806396db7d5c116101e25780639ef94737116101a75780639ef9473714610887578063a45e1e7f1461089f578063a4d7866e146108a7578063a5caf0f6146108af578063a64f5693146108d1578063a7a60914146108ec575f80fd5b806396db7d5c146108325780639781a8ca1461083c57806397b87b4a146108465780639835a0bd146108615780639d3d2a7814610874575f80fd5b806383f5d77a1161022857806383f5d77a146104f9578063841d2699146107d6578063847b575b146107e957806395861bd7146107fc57806396bac93114610817575f80fd5b8063798d5ba31461076757806379b79a801461077a5780637aadef8b1461078d5780637e2f35fa146107a857806381c8c425146107c3575f80fd5b80633484818b1161038657806358f2552e116103055780636521e19f116102ca5780636521e19f1461071c57806366760d7d146105145780636dc0ae22146107265780637000778e14610741578063727a7c841461074b578063752f1e3114610753575f80fd5b806358f2552e146106df5780635c517457146106fa5780636146195414610702578063623007321461070a57806364e9d56714610714575f80fd5b80634ca254251161034b5780634ca254251461066f578063533e0b3f146106825780635689daec14610695578063588c77e6146106b057806358bf3112146106cb575f80fd5b80633484818b1461061c5780633b80188f14610626578063444386141461063957806348bbb5571461064c57806349af5a9f14610667575f80fd5b806312e366aa1161041d57806325ad7f4d116103e257806325ad7f4d146105b05780632861c7d1146105cb57806328787d00146104c35780632b54c373146105e65780632d2c5565146105ee5780633427355814610609575f80fd5b806312e366aa146105655780631392d4ee1461057857806317c1ac9e1461058b578063194c0e181461059e5780631bbc51a7146105a8575f80fd5b80630bc9136e116104635780630bc9136e146104f95780630e6a204c146105015780630e8043aa14610516578063103f29071461052a57806311ae7a141461055d575f80fd5b8062623d7d1461049e5780630251eb11146104b9578063040e7a80146104c35780630731dc99146104cb5780630b396e66146104ef575b5f80fd5b6104a660db81565b6040519081526020015b60405180910390f35b6104a6620474a081565b6104a6606481565b6007546104df90600160b81b900460ff1681565b60405190151581526020016104b0565b6104a662048c1081565b6104a6607e81565b61051461050f366004613bd6565b610a61565b005b6007546104df90600160a01b900460ff1681565b61054573324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d81565b6040516001600160a01b0390911681526020016104b0565b6104a6607881565b610545610573366004613bf8565b610ab7565b5f5465010000000000900460ff166104df565b600554610545906001600160a01b031681565b6104a66205747c81565b6104a6606e81565b610545739efde135ca4832abf0408c44c6f5f370eb0f35e881565b6105457352aa899454998be5b000ad077a46bbe360f4e49781565b6104a6606781565b6105457328849d2b63fa8d361e5fc15cb8abb13019884d0981565b600754610545906001600160a01b031681565b6104a662062e0881565b610514610634366004613c23565b610b32565b610514610647366004613c23565b610baa565b61054573e7eb63a8b6392481a9fdebb108cfd580dc8664d381565b610514610c22565b61051461067d366004613c23565b610c63565b600354610545906001600160a01b031681565b610545732e4015880367b7c2613df77f816739d97a8c46ad81565b610545735c43aac965ff230ac1cf63e924d0153291d78bad81565b6007546104df90600160c81b900460ff1681565b61054573264786ef916af64a1db19f513f24a3681734ce9281565b610514610cdb565b610514610d1c565b6104a662030d4081565b6104a6606c81565b6104a6620493e081565b610545730204cd037b2ec03605cfdfe482d8e257c765fa1b81565b6104a662062a2081565b6104a6606a81565b6007546104df90600160b01b900460ff1681565b610514610775366004613c3e565b610d7e565b610514610788366004613c23565b610e0c565b610545732386dc45added673317ef068992f19421b481f4c81565b61054573059a94a72951c0ae1cc1ce3bf0db52421bbe821081565b6105146107d1366004613c23565b610e84565b6105456107e4366004613bf8565b610efc565b600454610545906001600160a01b031681565b61054573a0d3707c569ff8c87fa923d3823ec5d81c98be7881565b6105457354b91a0d94cb471f37f949c60f7fa7935b551d0381565b6104a66204a38081565b6104a66269492081565b6105457391716c4eda1fb55e84bf8b4c7085f84285c1908581565b600654610545906001600160a01b031681565b6104a6610882366004613cad565b610f36565b5f5460405164ffffffffff90911681526020016104b0565b6105146117b5565b6105146117f6565b6104df6108bd366004613bf8565b5f9081526001602052604090205460ff1690565b6105457397b0b3a8bdefe8cb9563a3c610019ad10db8ad1181565b6105146108fa366004613c23565b611837565b6104a6607281565b610514610915366004613d39565b6118af565b6104a6607081565b6105455f8051602061444783398151915281565b6104a66204ab5081565b6007546104df90600160c01b900460ff1681565b61054573a45f7bd6a5ff45d31aace6bcd3d426d9328cea0181565b610514611d55565b610545610985366004613c23565b611d96565b6105457f000000000000000000000000000000000000000000000000000000000000000081565b610514611e84565b6105456109c7366004613bf8565b611ec5565b600254610545906001600160a01b031681565b61054573e57227c7d5900165344b190fc7aa580bceb53b9b81565b6104a66204a76881565b6007546104df90600160a81b900460ff1681565b610545733daff61fe5cfb1f1b4ea7fba8173a58532ef184181565b610514610a41366004613dc8565b611eff565b610545731e2e1aed876f67fe4fd54090fd7b8f57ce23421981565b335f8051602061444783398151915214610a965760405162461bcd60e51b8152600401610a8d90613dec565b60405180910390fd5b5f8054911515650100000000000265ff000000000019909216919091179055565b604051630971b35560e11b8152600481018290525f907391716c4eda1fb55e84bf8b4c7085f84285c19085906312e366aa906024015b602060405180830381865afa158015610b08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2c9190613e17565b92915050565b335f8051602061444783398151915214610b5e5760405162461bcd60e51b8152600401610a8d90613dec565b600754600160a81b900460ff1615610b885760405162461bcd60e51b8152600401610a8d90613e32565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610bd65760405162461bcd60e51b8152600401610a8d90613dec565b600754600160b81b900460ff1615610c005760405162461bcd60e51b8152600401610a8d90613e32565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610c4e5760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60a01b1916600160a01b179055565b335f8051602061444783398151915214610c8f5760405162461bcd60e51b8152600401610a8d90613dec565b600754600160c01b900460ff1615610cb95760405162461bcd60e51b8152600401610a8d90613e32565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610d075760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60a81b1916600160a81b179055565b610d24612025565b610d2c612147565b610d34612698565b610d3c61287c565b610d44612c44565b610d4c612d1d565b610d54612eb9565b610d5c6130fc565b610d646132a3565b610d6c6133fc565b610d746134cb565b610d7c61362b565b565b335f8051602061444783398151915214610daa5760405162461bcd60e51b8152600401610a8d90613dec565b5f5b81811015610e07576001805f858585818110610dca57610dca613e52565b9050602002013581526020019081526020015f205f6101000a81548160ff0219169083151502179055508080610dff90613e7a565b915050610dac565b505050565b335f8051602061444783398151915214610e385760405162461bcd60e51b8152600401610a8d90613dec565b600754600160c81b900460ff1615610e625760405162461bcd60e51b8152600401610a8d90613e32565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b335f8051602061444783398151915214610eb05760405162461bcd60e51b8152600401610a8d90613dec565b600754600160b01b900460ff1615610eda5760405162461bcd60e51b8152600401610a8d90613e32565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60405163841d269960e01b8152600481018290525f9073e57227c7d5900165344b190fc7aa580bceb53b9b9063841d269990602401610aed565b5f8084118015610f4557505f83115b15610f925760405162461bcd60e51b815260206004820181905260248201527f626f74682075736420616e6420616d6f756e7420617265206e6f74207a65726f6044820152606401610a8d565b604080516001600160a01b03871660208083019190915260058284015282518083038401815260608301938490528051910120632d71cdb960e21b90925260648101919091525f907352aa899454998be5b000ad077a46bbe360f4e4979063b5c736e490608401602060405180830381865afa158015611014573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110389190613e92565b90505f80611045836137d9565b90925090505f601273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038b1601611080575062030d4090506012611736565b737f39c581f595b53c5cb19bd0b3f8da6c935e2c9f196001600160a01b038b16016110b357506205747c90506012611736565b73cd5fe23c85820f7b72d0926fc9b05b43e359b7ed196001600160a01b038b16016110e657506204a76890506012611736565b73a1290d69c65a6fe4df752f95823fae25cb99e5a6196001600160a01b038b1601611119575062048c1090506012611736565b73917cee801a67f933f2e6b33fc0cd1ed2d5909d87196001600160a01b038b160161114c5750620474a090506012611736565b73d5f7838f5c461feff7fe49ea5ebaf7728bb0adf9196001600160a01b038b160161117f57506204a38090506012611736565b73bf5495efe5db9ce00f80364c8b423567e58d210f196001600160a01b038b16016111b25750620493e090506012611736565b73f1c9acdc66974dfb6decb12aa385b9cd01190e37196001600160a01b038b16016111e557506204ab5090506012611736565b6001600160a01b038a1673cbb7c0000ab88b473b1f5afd9ef808440eed33bf148061122c57506001600160a01b038a16732260fac5e5542a773aa44fbcfedf7c193bc2c599145b8061125357506001600160a01b038a1673657e8c867d8b37dcc18fa4caead9c45eb088c642145b8061127a57506001600160a01b038a16738236a87084f8b84306f72007f36f2618a5634494145b1561128d57506269492090506008611736565b7318084fba666a33d37592fa2633fd49a74dd93a87196001600160a01b038b16016112c057506269492090506012611736565b6001600160a01b038a1673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48148061130757506001600160a01b038a1673dac17f958d2ee523a2206206994597c13d831ec7145b156113185750606490506006611736565b739d39a5de30e57443bff2a8307a4256c8797a3496196001600160a01b038b16016113495750607890506012611736565b73a3931d71877c0e7a3148cb7eb4463524fec27fbc196001600160a01b038b160161137a5750606c90506012611736565b73356b8d89c1e1239cbbb9de4815c39a1474d5ba7c196001600160a01b038b16016113ab5750606e90506006611736565b7380ac24aa929eaf5013f6436cda2a7ba190f5cc0a196001600160a01b038b16016113dc5750607290506006611736565b735086bf358635b81d8c47c66d1c8b9e567db70c71196001600160a01b038b160161140d5750606a90506012611736565b73beefc011e94f43b8b7b455ebab290c7ab4e216f0196001600160a01b038b160161143e5750606790506012611736565b73c58d044404d8b14e953c115e67823784dea53d8e196001600160a01b038b160161146f5750606490506012611736565b733d7d6fdf07ee548b939a80edbc9b2256d0cdc002196001600160a01b038b16016114a05750606490506012611736565b6001600160a01b038a167340d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14806114e757506001600160a01b038a16734c9edd5852cd905f086c759e8383e09bff1e68b3145b8061150e57506001600160a01b038a167315700b564ca08d9439c58ca5053166e8317aa138145b8061153557506001600160a01b038a167366a1e37c9b0eaddca17d3662d6c05f4decf3e110145b8061155c57506001600160a01b038a167373a15fed60bf67631dc6cd7bc5b6e8da8190acf5145b8061158357506001600160a01b038a1673085780639cc2cacd35e474e71f4d000e2405d8f6145b806115aa57506001600160a01b038a1673b01dd87b29d187f3e3a4bf6cdaebfb97f3d9ab98145b806115d157506001600160a01b038a167348f9e38f3070ad8945dfeae3fa70987722e3d89c145b806115f857506001600160a01b038a1673c139190f447e929f090edeb554d95abb8b18ac1c145b156116095750606490506012611736565b736f40d4a6237c257fff2db00fa0510deeecd303ea196001600160a01b038b160161163a575060db90506012611736565b731202f5c7b4b9e47a1a484e8b270be34dbbc75054196001600160a01b038b160161166b5750607090506012611736565b734956b52ae2ff65d74ca2d61207523288e4528f95196001600160a01b038b160161169c5750607e90506012611736565b7368749665ff8d2d112fa859aa293f07a622782f37196001600160a01b038b16016116cf575062062a2090506006611736565b7345804880de22913dafe09f4980848ece6ecbaf77196001600160a01b038b1601611702575062062e0890506012611736565b60405162461bcd60e51b81526020600482015260096024820152681b9bdd0b599bdd5b9960ba1b6044820152606401610a8d565b5f876117425783611744565b845b90508915611773578061175c8b64e8d4a51000613ea9565b6117669190613ed4565b96505050505050506117ad565b606461177f8285613ea9565b6117899190613ed4565b61179483600a613fd3565b6117a38b64e8d4a51000613ea9565b61175c9190613ea9565b949350505050565b335f80516020614447833981519152146117e15760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60b01b1916600160b01b179055565b335f80516020614447833981519152146118225760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60c01b1916600160c01b179055565b335f80516020614447833981519152146118635760405162461bcd60e51b8152600401610a8d90613dec565b600754600160a01b900460ff161561188d5760405162461bcd60e51b8152600401610a8d90613e32565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea0114806118dd5750335f80516020614447833981519152145b806118fb57503073059a94a72951c0ae1cc1ce3bf0db52421bbe8210145b80611919575030739efde135ca4832abf0408c44c6f5f370eb0f35e8145b80611937575030735c43aac965ff230ac1cf63e924d0153291d78bad145b80611955575030733daff61fe5cfb1f1b4ea7fba8173a58532ef1841145b8061197357503073e7eb63a8b6392481a9fdebb108cfd580dc8664d3145b6119b85760405162461bcd60e51b81526020600482015260166024820152751b5cd9cb9cd95b99195c8b5b9bdd0b585b1b1bddd95960521b6044820152606401610a8d565b6040805160018082528183019092525f9082602080830190803683370190505090505f8267ffffffffffffffff8111156119f4576119f4613cf4565b604051908082528060200260200182016040528015611a1d578160200160208202803683370190505b5090505f8367ffffffffffffffff811115611a3a57611a3a613cf4565b604051908082528060200260200182016040528015611a6d57816020015b6060815260200190600190039081611a585790505b5090505f8467ffffffffffffffff811115611a8a57611a8a613cf4565b604051908082528060200260200182016040528015611abd57816020015b6060815260200190600190039081611aa85790505b509050732386dc45added673317ef068992f19421b481f4c845f81518110611ae757611ae7613e52565b60200260200101906001600160a01b031690816001600160a01b0316815250505f835f81518110611b1a57611b1a613e52565b60200260200101818152505060405180606001604052806024815260200161442360249139825f81518110611b5157611b51613e52565b602090810291909101810191909152604080515f81529182018152611b99917f0000000000000000000000000000000000000000000000000000000000000000918101614021565b604051602081830303815290604052815f81518110611bba57611bba613e52565b6020908102919091010152604051636d4ab48d60e11b81525f90730204cd037b2ec03605cfdfe482d8e257c765fa1b9063da95691a90611c069088908890889088908e906004016140ed565b6020604051808303815f875af1158015611c22573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c469190613e92565b9050607e8114611c8f5760405162461bcd60e51b815260206004820152601460248201527350524f504f53414c5f49535f4e4f545f53414d4560601b6044820152606401610a8d565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea011480611cbd5750335f80516020614447833981519152145b15611cd057611ccb42611eff565b611d4c565b604051631f615d2360e31b815264ffffffffff421660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fb0ae918906024015f604051808303815f87803b158015611d35575f80fd5b505af1158015611d47573d5f803e3d5ffd5b505050505b50505050505050565b335f8051602061444783398151915214611d815760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60b81b1916600160b81b179055565b5f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc1196001600160a01b03831601611e25576040805163bb4a64d360e01b81526001600160a01b03841660048201526024810191909152601060448201526f4e6174697665556e6465726c79696e6760801b60648201527354b91a0d94cb471f37f949c60f7fa7935b551d039063bb4a64d390608401610aed565b6040805163bb4a64d360e01b81526001600160a01b038416600482015260248101919091526006604482015265332a37b5b2b760d11b60648201527354b91a0d94cb471f37f949c60f7fa7935b551d039063bb4a64d390608401610aed565b335f8051602061444783398151915214611eb05760405162461bcd60e51b8152600401610a8d90613dec565b6007805460ff60c81b1916600160c81b179055565b60405163735e935160e11b8152600481018290525f9073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d9063e6bd26a290602401610aed565b3373a45f7bd6a5ff45d31aace6bcd3d426d9328cea011480611f2d5750335f80516020614447833981519152145b80611f4b57503373059a94a72951c0ae1cc1ce3bf0db52421bbe8210145b80611f69575033739efde135ca4832abf0408c44c6f5f370eb0f35e8145b80611f87575033735c43aac965ff230ac1cf63e924d0153291d78bad145b80611fa5575033733daff61fe5cfb1f1b4ea7fba8173a58532ef1841145b80611fc357503373e7eb63a8b6392481a9fdebb108cfd580dc8664d3145b6120085760405162461bcd60e51b81526020600482015260166024820152751b5cd9cb9cd95b99195c8b5b9bdd0b585b1b1bddd95960521b6044820152606401610a8d565b5f805464ffffffffff191664ffffffffff92909216919091179055565b30732386dc45added673317ef068992f19421b481f4c1461207b5760405162461bcd60e51b815260206004820152601060248201526f3737ba16bb30b634b216b1b0b63632b960811b6044820152606401610a8d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631392d4ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120fb919061418b565b610d7c5760405162461bcd60e51b815260206004820152601760248201527f70726f706f73616c2d6e6f742d65786563757461626c650000000000000000006044820152606401610a8d565b6040516352e5787b60e11b8152600160048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d1919061418b565b6126955773324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d637faa1d216121f9606e611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612227939291906141a6565b5f604051808303815f87803b15801561223e575f80fd5b505af1158015612250573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d21612281606f611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016122af939291906141a6565b5f604051808303815f87803b1580156122c6575f80fd5b505af11580156122d8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216123096070611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612337939291906141a6565b5f604051808303815f87803b15801561234e575f80fd5b505af1158015612360573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216123916085611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016123bf939291906141a6565b5f604051808303815f87803b1580156123d6575f80fd5b505af11580156123e8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216124196086611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612447939291906141a6565b5f604051808303815f87803b15801561245e575f80fd5b505af1158015612470573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216124a16087611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016124cf939291906141a6565b5f604051808303815f87803b1580156124e6575f80fd5b505af11580156124f8573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d21612529608f611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612557939291906141a6565b5f604051808303815f87803b15801561256e575f80fd5b505af1158015612580573d5f803e3d5ffd5b5050505073324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d6001600160a01b0316637faa1d216125b16090611ec5565b5f8051602061444783398151915260016040518463ffffffff1660e01b81526004016125df939291906141a6565b5f604051808303815f87803b1580156125f6575f80fd5b505af1158015612608573d5f803e3d5ffd5b505050507391716c4eda1fb55e84bf8b4c7085f84285c190856001600160a01b03166378c7e138612639601b610ab7565b5f8051602061444783398151915260016040518463ffffffff1660e01b8152600401612667939291906141a6565b5f604051808303815f87803b15801561267e575f80fd5b505af1158015612690573d5f803e3d5ffd5b505050505b50565b6040516352e5787b60e11b8152600260048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156126fe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612722919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ed3660c56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612783573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127a79190613e17565b90506001600160a01b0381166127f55760405162461bcd60e51b81526020600482015260136024820152721d5cd95c8b5b5bd91d5b194b5b9bdd0b5cd95d606a1b6044820152606401610a8d565b604051633ff8b31d60e01b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201526001600160a01b03821660248201527352aa899454998be5b000ad077a46bbe360f4e49790633ff8b31d906044015b5f604051808303815f87803b158015612862575f80fd5b505af1158015612874573d5f803e3d5ffd5b505050505050565b6040516352e5787b60e11b8152600360048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa1580156128e2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612906919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ed3660c56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061298b9190613e17565b90506001600160a01b0381166129d95760405162461bcd60e51b81526020600482015260136024820152721d5cd95c8b5b5bd91d5b194b5b9bdd0b5cd95d606a1b6044820152606401610a8d565b6040516311272db960e31b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201525f907352aa899454998be5b000ad077a46bbe360f4e497906389396dc8906024015f60405180830381865afa158015612a3b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612a6291908101906141ca565b80519091505f612a73826001614278565b67ffffffffffffffff811115612a8b57612a8b613cf4565b604051908082528060200260200182016040528015612ab4578160200160208202803683370190505b5090505f5b82811015612b1657838181518110612ad357612ad3613e52565b6020026020010151828281518110612aed57612aed613e52565b6001600160e01b031990921660209283029190910190910152612b0f81613e7a565b9050612ab9565b507fdacb5419b3a364d15c0a7f04c12b64c98b665a88e8f945fd69383fb36d00d2d2818381518110612b4a57612b4a613e52565b6001600160e01b0319929092166020928302919091019091015260405163110bad1960e11b8152732e4015880367b7c2613df77f816739d97a8c46ad60048201527352aa899454998be5b000ad077a46bbe360f4e497906322175a32906024015f604051808303815f87803b158015612bc1575f80fd5b505af1158015612bd3573d5f803e3d5ffd5b50506040516378600da160e11b81527352aa899454998be5b000ad077a46bbe360f4e497925063f0c01b429150612c10908790859060040161428b565b5f604051808303815f87803b158015612c27575f80fd5b505af1158015612c39573d5f803e3d5ffd5b505050505050505050565b6040516352e5787b60e11b81526004808201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612ca9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ccd919061418b565b612695577352aa899454998be5b000ad077a46bbe360f4e4976001600160a01b031663981c829f6040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561267e575f80fd5b6040516352e5787b60e11b8152600560048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612d83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612da7919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663533e0b3f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e2c9190613e17565b90506001600160a01b038116612e795760405162461bcd60e51b8152602060048201526012602482015271191d5b5b5e4b5a5b5c1b0b5b9bdd0b5cd95d60721b6044820152606401610a8d565b60405163c39aa07d60e01b81526001600160a01b03821660048201527352aa899454998be5b000ad077a46bbe360f4e4979063c39aa07d9060240161284b565b6040516352e5787b60e11b8152600660048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015612f1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f43919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663847b575b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fa4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fc89190613e17565b90506001600160a01b0381166130205760405162461bcd60e51b815260206004820152601960248201527f6f6e2d626568616c662d6f662d617574682d6e6f742d736574000000000000006044820152606401610a8d565b6040805160018082528183019092525f91816020015b604080518082019091525f80825260208201528152602001906001900390816130365790505090506040518060400160405280836001600160a01b0316815260200160011515815250815f8151811061309157613091613e52565b6020908102919091010152604051633f66feff60e01b81527352aa899454998be5b000ad077a46bbe360f4e49790633f66feff906130d39084906004016142ea565b5f604051808303815f87803b1580156130ea575f80fd5b505af1158015611d4c573d5f803e3d5ffd5b6040516352e5787b60e11b8152600760048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613162573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613186919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166317c1ac9e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061320b9190613e17565b90506001600160a01b0381166132635760405162461bcd60e51b815260206004820152601b60248201527f7661756c742d666163746f72792d6f776e65722d6e6f742d73657400000000006044820152606401610a8d565b60405163f2fde38b60e01b81526001600160a01b038216600482015273324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d9063f2fde38b9060240161284b565b6040516352e5787b60e11b8152600860048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613309573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061332d919061418b565b6126955761335861333e606e611ec5565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486139ce565b61337f613365606f611ec5565b73dac17f958d2ee523a2206206994597c13d831ec76139ce565b6133a661338c6070611ec5565b7340d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f6139ce565b6133b361333e6085611ec5565b5f6133be6002610ab7565b90505f6133cb6022610ab7565b90506133e0826133db6086611ec5565b613ae9565b6133ee826133db608f611ec5565b610e07816133db6090611ec5565b6040516352e5787b60e11b8152600960048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613462573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613486919061418b565b61269557613494601b610ab7565b6001600160a01b03166382df16526040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561267e575f80fd5b6040516352e5787b60e11b8152600a60048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613531573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613555919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639835a0bd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135b6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135da9190613e17565b90506001600160a01b0381166130205760405162461bcd60e51b81526020600482015260166024820152751c185d5cd958589b194b585d5d1a0b5b9bdd0b5cd95d60521b6044820152606401610a8d565b6040516352e5787b60e11b8152600b60048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5caf0f690602401602060405180830381865afa158015613691573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136b5919061418b565b612695575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663342735586040518163ffffffff1660e01b8152600401602060405180830381865afa158015613716573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061373a9190613e17565b90506001600160a01b0381166137925760405162461bcd60e51b815260206004820152601960248201527f7061757361626c652d6465782d617574682d6e6f742d736574000000000000006044820152606401610a8d565b604051638f2db95d60e01b81526001600160a01b0382166004820152600160248201527391716c4eda1fb55e84bf8b4c7085f84285c1908590638f2db95d9060440161284b565b67ffffffffffffffff605b82901c811690609b83901c168115806137fb575080155b1561381e57604051636a86ba8960e11b8152620111716004820152602401610a8d565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480613848575082155b806138535750806001145b1561386057505050915091565b64496cebb80084840283020484019350617fff60db87901c1692508260010361388b57505050915091565b826001166001036138e05760019290921c91826c7e37be2022c0914b2680000000816138b9576138b9613ec0565b049250612710601e87901c613fff166b033b2e3c9fd0803ce800000085010204925061390d565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b806001166001036139445760011c61271081016b033b2e3c9fd0803ce800000082028161393c5761393c613ec0565b04905061397a565b60011c61271081016b033b2e3c9fd0803ce800000082028161396857613968613ec0565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b6040805160018082528183019092525f91816020015b613a326040518060e001604052805f6001600160a01b031681526020015f6001600160a01b031681526020015f60ff1681526020015f81526020015f81526020015f81526020015f81525090565b8152602001906001900390816139e45790505090506040518060e00160405280846001600160a01b03168152602001836001600160a01b03168152602001600160ff1681526020016001815260200162ffffff8152602001600a81526020016014815250815f81518110613aa857613aa8613e52565b602090810291909101015260405162dc47c360e11b81527352aa899454998be5b000ad077a46bbe360f4e497906301b88f86906130d3908490600401614336565b6040805160018082528183019092525f91816020015b613b356040518060a001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81525090565b815260200190600190039081613aff5790505090506040518060a00160405280836001600160a01b031681526020016001815260200162ffffff8152602001600a81526020016014815250815f81518110613b9257613b92613e52565b602090810291909101015260405163ba9af1e360e01b81526001600160a01b0384169063ba9af1e3906130d39084906004016143b9565b8015158114612695575f80fd5b5f60208284031215613be6575f80fd5b8135613bf181613bc9565b9392505050565b5f60208284031215613c08575f80fd5b5035919050565b6001600160a01b0381168114612695575f80fd5b5f60208284031215613c33575f80fd5b8135613bf181613c0f565b5f8060208385031215613c4f575f80fd5b823567ffffffffffffffff80821115613c66575f80fd5b818501915085601f830112613c79575f80fd5b813581811115613c87575f80fd5b8660208260051b8501011115613c9b575f80fd5b60209290920196919550909350505050565b5f805f8060808587031215613cc0575f80fd5b8435613ccb81613c0f565b935060208501359250604085013591506060850135613ce981613bc9565b939692955090935050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613d3157613d31613cf4565b604052919050565b5f6020808385031215613d4a575f80fd5b823567ffffffffffffffff80821115613d61575f80fd5b818501915085601f830112613d74575f80fd5b813581811115613d8657613d86613cf4565b613d98601f8201601f19168501613d08565b91508082528684828501011115613dad575f80fd5b80848401858401375f90820190930192909252509392505050565b5f60208284031215613dd8575f80fd5b813564ffffffffff81168114613bf1575f80fd5b6020808252601190820152706e6f742d7465616d2d6d756c746973696760781b604082015260600190565b5f60208284031215613e27575f80fd5b8151613bf181613c0f565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201613e8b57613e8b613e66565b5060010190565b5f60208284031215613ea2575f80fd5b5051919050565b8082028115828204841417610b2c57610b2c613e66565b634e487b7160e01b5f52601260045260245ffd5b5f82613eee57634e487b7160e01b5f52601260045260245ffd5b500490565b600181815b80851115613f2d57815f1904821115613f1357613f13613e66565b80851615613f2057918102915b93841c9390800290613ef8565b509250929050565b5f82613f4357506001610b2c565b81613f4f57505f610b2c565b8160018114613f655760028114613f6f57613f8b565b6001915050610b2c565b60ff841115613f8057613f80613e66565b50506001821b610b2c565b5060208310610133831016604e8410600b8410161715613fae575081810a610b2c565b613fb88383613ef3565b805f1904821115613fcb57613fcb613e66565b029392505050565b5f613bf18383613f35565b5f81518084525f5b8181101561400257602081850181015186830182015201613fe6565b505f602082860101526020601f19601f83011685010191505092915050565b60018060a01b038316815260606020820152600960608201526865786563757465282960b81b608082015260a060408201525f6117ad60a0830184613fde565b5f8151808452602080850194508084015f5b8381101561408f57815187529582019590820190600101614073565b509495945050505050565b5f81518084526020808501808196508360051b810191508286015f5b858110156140e05782840389526140ce848351613fde565b988501989350908401906001016140b6565b5091979650505050505050565b60a080825286519082018190525f9060209060c0840190828a01845b8281101561412e5781516001600160a01b031684529284019290840190600101614109565b505050838103828501526141428189614061565b9150508281036040840152614157818761409a565b9050828103606084015261416b818661409a565b9050828103608084015261417f8185613fde565b98975050505050505050565b5f6020828403121561419b575f80fd5b8151613bf181613bc9565b6001600160a01b039384168152919092166020820152901515604082015260600190565b5f60208083850312156141db575f80fd5b825167ffffffffffffffff808211156141f2575f80fd5b818501915085601f830112614205575f80fd5b81518181111561421757614217613cf4565b8060051b9150614228848301613d08565b8181529183018401918481019088841115614241575f80fd5b938501935b8385101561417f57845192506001600160e01b031983168314614268575f8081fd5b8282529385019390850190614246565b80820180821115610b2c57610b2c613e66565b6001600160a01b03831681526040602080830182905283519183018290525f9184820191906060850190845b818110156142dd5784516001600160e01b031916835293830193918301916001016142b7565b5090979650505050505050565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b031685528601511515868501529284019290850190600101614306565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b0390811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0808201519086015260c0908101519085015260e09093019290850190600101614352565b602080825282518282018190525f919060409081850190868401855b828110156140e057815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080908101519085015260a090930192908501906001016143d556fe657865637574655061796c6f616428616464726573732c737472696e672c6279746573290000000000000000000000004f6f977acdd1177dcd81ab83074855ecb9c2d49ea2646970667358221220cc4fd4303a28ea03114d3976a3e0fae3acfc265462710b0fd7d5048563ccdd2064736f6c63430008150033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"PayloadModule#PayloadIGP126","networkInteractionId":1,"nonce":370,"type":"TRANSACTION_PREPARE_SEND"} +{"futureId":"PayloadModule#PayloadIGP126","networkInteractionId":1,"nonce":370,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"421230918"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"100"}},"hash":"0x1b11f9ae61ad3a605396a2fa796a91a89c9467e4b69566d77960b7dc7010de55"},"type":"TRANSACTION_SEND"} +{"futureId":"PayloadModule#PayloadIGP126","hash":"0x1b11f9ae61ad3a605396a2fa796a91a89c9467e4b69566d77960b7dc7010de55","networkInteractionId":1,"receipt":{"blockHash":"0x3cf6fb751cbc780d2bdc3e99a25e14c1cd5ffa745268d95e02bc5ca6d1404fb7","blockNumber":24728813,"contractAddress":"0x987CB30d3a92982E0080FF7f59793899232A4F32","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"PayloadModule#PayloadIGP126","result":{"address":"0x987CB30d3a92982E0080FF7f59793899232A4F32","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} \ No newline at end of file diff --git a/scripts/simulate.ts b/scripts/simulate.ts index ab5c6860..debafd3d 100644 --- a/scripts/simulate.ts +++ b/scripts/simulate.ts @@ -519,7 +519,7 @@ class TenderlyGovernanceSimulator { } } - async runPreSetup(provider: JsonRpcProvider): Promise { + async runPreSetup(provider: JsonRpcProvider, payloadAddress?: string): Promise { console.log('\n=== Step 3: Running Pre-Setup (if available) ==='); const setupPath = path.join( @@ -542,7 +542,7 @@ class TenderlyGovernanceSimulator { if (typeof setupModule.preSetup === 'function') { console.log('Executing preSetup...'); - await setupModule.preSetup(provider); + await setupModule.preSetup(provider, payloadAddress); console.log('[SUCCESS] Pre-setup completed'); console.log('[STAGE:COMPLETED] preSetup'); } @@ -1152,7 +1152,7 @@ ${vnetSection} staticNetwork: true, polling: false }); - await this.runPreSetup(provider); + await this.runPreSetup(provider, payloadAddress); const result = await this.runGovernanceSimulation(vnetConfig, payloadAddress);