├── .env.example ├── .gas-snapshot ├── .github ├── CODEOWNERS └── workflows │ ├── pr.yml │ ├── release.yml │ └── release_prod.yml ├── .gitignore ├── .gitmodules ├── .husky └── pre-commit ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .solhint.json ├── .solhintignore ├── .vscode ├── extensions.json └── settings.json ├── LICENSE ├── README.md ├── abi ├── AaveV2Strategy.json ├── AaveV3Strategy.json ├── AccessControl.json ├── AccessControlUpgradeable.json ├── AccessStrategy.json ├── AffineDelegator.json ├── AffineGenesis.json ├── AffineGovernable.json ├── AffinePass.json ├── AffinePassBridge.json ├── AffineReStaking.json ├── AffineVault.json ├── AggregatorV3Interface.json ├── BaseStrategy.json ├── BaseStrategyVault.json ├── BaseVault.json ├── BeaconProxy.json ├── BeefyAeroStrategy.json ├── BeefyEpochStrategy.json ├── BeefyPearlEpochStrategy.json ├── BeefyPearlStrategy.json ├── BeefyStrategy.json ├── BridgeEscrow.json ├── CCIPReceiver.json ├── Client.json ├── CompoundV3Strategy.json ├── ContextUpgradeable.json ├── ConvexStrategy.json ├── DegenEthVault.json ├── DegenVault.json ├── DegenVaultV2.json ├── DegenVaultV2Eth.json ├── DelegatorBeacon.json ├── DelegatorFactory.json ├── DeltaNeutralLp.json ├── DeltaNeutralLpV3.json ├── DetailedShare.json ├── DummyEpochStrategy.json ├── DummyRelay.json ├── ERC165.json ├── ERC165Upgradeable.json ├── ERC1967Upgrade.json ├── ERC1967UpgradeUpgradeable.json ├── ERC20Upgradeable.json ├── ERC4626Router.json ├── ERC4626RouterBase.json ├── ERC4626Upgradeable.json ├── ERC721A.json ├── ERC721A__IERC721Receiver.json ├── ERC721Burnable.json ├── ERC721Enumerable.json ├── ERC721TokenReceiver.json ├── EigenDelegator.json ├── EmergencyWithdrawalQueue.json ├── EthVault.json ├── EthVaultV2.json ├── Forwarder.json ├── HarvestStorage.json ├── HighYieldLpVaultEth.json ├── I3CrvMetaPoolZap.json ├── IAToken.json ├── IAaveIncentivesController.json ├── IAccessControl.json ├── IAccessControlUpgradeable.json ├── IAeroPool.json ├── IAeroRouter.json ├── IAllowanceTransfer.json ├── IAny2EVMMessageReceiver.json ├── IBalancerQueries.json ├── IBalancerVault.json ├── IBeacon.json ├── IBeaconUpgradeable.json ├── IBeefyVault.json ├── ICREATE3Factory.json ├── ICToken.json ├── ICdpManager.json ├── IChildERC20.json ├── IChildPool.json ├── ICollateral.json ├── IComet.json ├── IComptroller.json ├── IConvexBooster.json ├── IConvexRewards.json ├── ICropper.json ├── ICurvePool.json ├── IDefaultCollateral.json ├── IDelegationManager.json ├── IDelegator.json ├── IDelegatorBeacon.json ├── IDelegatorFactory.json ├── IEIP712.json ├── IERC165Upgradeable.json ├── IERC1822Proxiable.json ├── IERC1822ProxiableUpgradeable.json ├── IERC20.json ├── IERC20Metadata.json ├── IERC20MetadataUpgradeable.json ├── IERC20Permit.json ├── IERC20PermitUpgradeable.json ├── IERC20Upgradeable.json ├── IERC4626.json ├── IERC4626Upgradeable.json ├── IERC721.json ├── IERC721A.json ├── IERC721Enumerable.json ├── IERC721Metadata.json ├── IERC721Permit.json ├── IERC721Receiver.json ├── IFlashLoanReceiver.json ├── IFlashLoanRecipient.json ├── IGemJoin.json ├── IInitializableAToken.json ├── ILendingPool.json ├── ILendingPoolAddressesProvider.json ├── ILiquidityGauge.json ├── IMakerAdapter.json ├── IMasterChef.json ├── IMinter.json ├── INonfungiblePositionManager.json ├── IPair.json ├── IPeripheryImmutableState.json ├── IPeripheryPayments.json ├── IPermit2.json ├── IPool.json ├── IPoolAddressesProvider.json ├── IPoolInitializer.json ├── IProtocolDataProvider.json ├── IRewards.json ├── IRootChainManager.json ├── IRouter.json ├── IRouterClient.json ├── IScaledBalanceToken.json ├── ISignatureTransfer.json ├── IStEth.json ├── IStrategy.json ├── IStrategyManager.json ├── ISwapRouter.json ├── IUltraLRT.json ├── IUniPositionValue.json ├── IUniswapV2Factory.json ├── IUniswapV2Router01.json ├── IUniswapV2Router02.json ├── IUniswapV3Pool.json ├── IUniswapV3PoolActions.json ├── IUniswapV3PoolDerivedState.json ├── IUniswapV3PoolErrors.json ├── IUniswapV3PoolEvents.json ├── IUniswapV3PoolImmutables.json ├── IUniswapV3PoolOwnerActions.json ├── IUniswapV3PoolState.json ├── IUniswapV3SwapCallback.json ├── IVat.json ├── IWETH.json ├── IWSTETH.json ├── IWormhole.json ├── Initializable.json ├── L1BridgeEscrow.json ├── L1CompoundStrategy.json ├── L1Vault.json ├── L1WormholeRouter.json ├── L2BridgeEscrow.json ├── L2USDEarnVault.json ├── L2Vault.json ├── L2VaultV2.json ├── L2WormholeRouter.json ├── LevMaticXLoopStrategy.json ├── LidoLev.json ├── LidoLevEthStrategy.json ├── LidoLevL2.json ├── LidoLevV3.json ├── LockedWithdrawalEscrow.json ├── MinimalForwarder.json ├── MockERC20.json ├── MockEpochStrategy.json ├── Multicallable.json ├── NftGate.json ├── Ownable.json ├── OwnableUpgradeable.json ├── PausableUpgradeable.json ├── Proxy.json ├── ReStakingErrors.json ├── RebalanceModule.json ├── RebalanceStorage.json ├── ReentrancyGuard.json ├── ReentrancyGuardUpgradeable.json ├── Router.json ├── SSVDeltaNeutralLp.json ├── SmartWallet.json ├── StaderLevMaticStrategy.json ├── StrategyVault.json ├── StrategyVaultV2.json ├── StrikeEthStrategy.json ├── SymDelegatorFactory.json ├── SymbioticDelegator.json ├── TwoAssetBasket.json ├── UUPSUpgradeable.json ├── UltraLRT.json ├── UltraLRTRouter.json ├── UltraLRTStorage.json ├── UpgradeableBeacon.json ├── Vault.json ├── VaultErrors.json ├── VaultV2.json ├── WETH.json ├── WithdrawalEscrow.json ├── WithdrawalEscrowV2.json └── WormholeRouter.json ├── audits ├── Affine_DeFi_Multiplyr_Smart_Contract_Security_Audit_Report_Halborn_Final_oct_22.pdf ├── Affine_ultraETH_LRT_Audit_May24_MaslarovK_Final.pdf └── Affine_ultraETH_LRT_Audit_Quantstamp_June24_Final.pdf ├── docs ├── coverage │ ├── amber.png │ ├── emerald.png │ ├── gcov.css │ ├── glass.png │ ├── index-sort-f.html │ ├── index-sort-l.html │ ├── index.html │ ├── ruby.png │ ├── script │ │ ├── Base.sol.func-sort-c.html │ │ ├── Base.sol.func.html │ │ ├── Base.sol.gcov.html │ │ ├── DeltaNeutralLpV3.s.sol.func-sort-c.html │ │ ├── DeltaNeutralLpV3.s.sol.func.html │ │ ├── DeltaNeutralLpV3.s.sol.gcov.html │ │ ├── L1.s.sol.func-sort-c.html │ │ ├── L1.s.sol.func.html │ │ ├── L1.s.sol.gcov.html │ │ ├── L2.s.sol.func-sort-c.html │ │ ├── L2.s.sol.func.html │ │ ├── L2.s.sol.gcov.html │ │ ├── index-sort-f.html │ │ ├── index-sort-l.html │ │ └── index.html │ ├── snow.png │ ├── src │ │ ├── Affine4626.sol.func-sort-c.html │ │ ├── Affine4626.sol.func.html │ │ ├── Affine4626.sol.gcov.html │ │ ├── AffineGovernable.sol.func-sort-c.html │ │ ├── AffineGovernable.sol.func.html │ │ ├── AffineGovernable.sol.gcov.html │ │ ├── AffineVault.sol.func-sort-c.html │ │ ├── AffineVault.sol.func.html │ │ ├── AffineVault.sol.gcov.html │ │ ├── BaseStrategy.sol.func-sort-c.html │ │ ├── BaseStrategy.sol.func.html │ │ ├── BaseStrategy.sol.gcov.html │ │ ├── BaseVault.sol.func-sort-c.html │ │ ├── BaseVault.sol.func.html │ │ ├── BaseVault.sol.gcov.html │ │ ├── BridgeEscrow.sol.func-sort-c.html │ │ ├── BridgeEscrow.sol.func.html │ │ ├── BridgeEscrow.sol.gcov.html │ │ ├── DeltaNeutralLp.sol.func-sort-c.html │ │ ├── DeltaNeutralLp.sol.func.html │ │ ├── DeltaNeutralLp.sol.gcov.html │ │ ├── WormholeRouter.sol.func-sort-c.html │ │ ├── WormholeRouter.sol.func.html │ │ ├── WormholeRouter.sol.gcov.html │ │ ├── ethereum │ │ │ ├── ConvexStrategy.sol.func-sort-c.html │ │ │ ├── ConvexStrategy.sol.func.html │ │ │ ├── ConvexStrategy.sol.gcov.html │ │ │ ├── CurveStrategy.sol.func-sort-c.html │ │ │ ├── CurveStrategy.sol.func.html │ │ │ ├── CurveStrategy.sol.gcov.html │ │ │ ├── L1BridgeEscrow.sol.func-sort-c.html │ │ │ ├── L1BridgeEscrow.sol.func.html │ │ │ ├── L1BridgeEscrow.sol.gcov.html │ │ │ ├── L1CompoundStrategy.sol.func-sort-c.html │ │ │ ├── L1CompoundStrategy.sol.func.html │ │ │ ├── L1CompoundStrategy.sol.gcov.html │ │ │ ├── L1Vault.sol.func-sort-c.html │ │ │ ├── L1Vault.sol.func.html │ │ │ ├── L1Vault.sol.gcov.html │ │ │ ├── L1WormholeRouter.sol.func-sort-c.html │ │ │ ├── L1WormholeRouter.sol.func.html │ │ │ ├── L1WormholeRouter.sol.gcov.html │ │ │ ├── Vault.sol.func-sort-c.html │ │ │ ├── Vault.sol.func.html │ │ │ ├── Vault.sol.gcov.html │ │ │ ├── index-sort-f.html │ │ │ ├── index-sort-l.html │ │ │ └── index.html │ │ ├── index-sort-f.html │ │ ├── index-sort-l.html │ │ ├── index.html │ │ ├── libs │ │ │ ├── DollarMath.sol.func-sort-c.html │ │ │ ├── DollarMath.sol.func.html │ │ │ ├── DollarMath.sol.gcov.html │ │ │ ├── SlippageUtils.sol.func-sort-c.html │ │ │ ├── SlippageUtils.sol.func.html │ │ │ ├── SlippageUtils.sol.gcov.html │ │ │ ├── index-sort-f.html │ │ │ ├── index-sort-l.html │ │ │ └── index.html │ │ ├── polygon │ │ │ ├── DeltaNeutralLpV3.sol.func-sort-c.html │ │ │ ├── DeltaNeutralLpV3.sol.func.html │ │ │ ├── DeltaNeutralLpV3.sol.gcov.html │ │ │ ├── ERC4626Router.sol.func-sort-c.html │ │ │ ├── ERC4626Router.sol.func.html │ │ │ ├── ERC4626Router.sol.gcov.html │ │ │ ├── ERC4626RouterBase.sol.func-sort-c.html │ │ │ ├── ERC4626RouterBase.sol.func.html │ │ │ ├── ERC4626RouterBase.sol.gcov.html │ │ │ ├── EmergencyWithdrawalQueue.sol.func-sort-c.html │ │ │ ├── EmergencyWithdrawalQueue.sol.func.html │ │ │ ├── EmergencyWithdrawalQueue.sol.gcov.html │ │ │ ├── Forwarder.sol.func-sort-c.html │ │ │ ├── Forwarder.sol.func.html │ │ │ ├── Forwarder.sol.gcov.html │ │ │ ├── L2AAVEStrategy.sol.func-sort-c.html │ │ │ ├── L2AAVEStrategy.sol.func.html │ │ │ ├── L2AAVEStrategy.sol.gcov.html │ │ │ ├── L2BridgeEscrow.sol.func-sort-c.html │ │ │ ├── L2BridgeEscrow.sol.func.html │ │ │ ├── L2BridgeEscrow.sol.gcov.html │ │ │ ├── L2Vault.sol.func-sort-c.html │ │ │ ├── L2Vault.sol.func.html │ │ │ ├── L2Vault.sol.gcov.html │ │ │ ├── L2WormholeRouter.sol.func-sort-c.html │ │ │ ├── L2WormholeRouter.sol.func.html │ │ │ ├── L2WormholeRouter.sol.gcov.html │ │ │ ├── Router.sol.func-sort-c.html │ │ │ ├── Router.sol.func.html │ │ │ ├── Router.sol.gcov.html │ │ │ ├── TwoAssetBasket.sol.func-sort-c.html │ │ │ ├── TwoAssetBasket.sol.func.html │ │ │ ├── TwoAssetBasket.sol.gcov.html │ │ │ ├── index-sort-f.html │ │ │ ├── index-sort-l.html │ │ │ └── index.html │ │ ├── test │ │ │ ├── BaseVault.t.sol.func-sort-c.html │ │ │ ├── BaseVault.t.sol.func.html │ │ │ ├── BaseVault.t.sol.gcov.html │ │ │ ├── CREATE3Factory.sol.func-sort-c.html │ │ │ ├── CREATE3Factory.sol.func.html │ │ │ ├── CREATE3Factory.sol.gcov.html │ │ │ ├── ConvertLib.sol.func-sort-c.html │ │ │ ├── ConvertLib.sol.func.html │ │ │ ├── ConvertLib.sol.gcov.html │ │ │ ├── Create3Deployer.sol.func-sort-c.html │ │ │ ├── Create3Deployer.sol.func.html │ │ │ ├── Create3Deployer.sol.gcov.html │ │ │ ├── Deploy.sol.func-sort-c.html │ │ │ ├── Deploy.sol.func.html │ │ │ ├── Deploy.sol.gcov.html │ │ │ ├── TestPlus.sol.func-sort-c.html │ │ │ ├── TestPlus.sol.func.html │ │ │ ├── TestPlus.sol.gcov.html │ │ │ ├── Wormhole.t.sol.func-sort-c.html │ │ │ ├── Wormhole.t.sol.func.html │ │ │ ├── Wormhole.t.sol.gcov.html │ │ │ ├── index-sort-f.html │ │ │ ├── index-sort-l.html │ │ │ ├── index.html │ │ │ └── mocks │ │ │ │ ├── MockERC20.sol.func-sort-c.html │ │ │ │ ├── MockERC20.sol.func.html │ │ │ │ ├── MockERC20.sol.gcov.html │ │ │ │ ├── TestStrategy.sol.func-sort-c.html │ │ │ │ ├── TestStrategy.sol.func.html │ │ │ │ ├── TestStrategy.sol.gcov.html │ │ │ │ ├── index-sort-f.html │ │ │ │ ├── index-sort-l.html │ │ │ │ ├── index.html │ │ │ │ ├── index.sol.func-sort-c.html │ │ │ │ ├── index.sol.func.html │ │ │ │ └── index.sol.gcov.html │ │ └── testnet │ │ │ ├── MockERC20.sol.func-sort-c.html │ │ │ ├── MockERC20.sol.func.html │ │ │ ├── MockERC20.sol.gcov.html │ │ │ ├── index-sort-f.html │ │ │ ├── index-sort-l.html │ │ │ └── index.html │ └── updown.png └── tests │ └── index.md ├── foundry.toml ├── gencov.sh ├── hardhat.config.ts ├── package.json ├── remappings.txt ├── script ├── AAVEV3Strategy.s.sol ├── AaveV2Strategy.s.sol ├── AffinePassBridge.s.sol ├── Base.sol ├── BaseVault.s.sol ├── BeefyStrategy.s.sol ├── CompoundV3Strategy.s.sol ├── ConvexStrategy.s.sol ├── DegenEthVault.s.sol ├── DeltaNeutralLp.s.sol ├── DeltaNeutralLpV3.s.sol ├── EthEntry.s.sol ├── EthLeverage.s.sol ├── EthVaults.s.sol ├── L1.s.sol ├── L2.s.sol ├── LidoLev.s.sol ├── LidoLevL2.s.sol ├── LidoLevV3.s.sol ├── ReStaking.s.sol ├── SmartWallet.s.sol ├── StaderLevMatic.s.sol ├── StrikeLevStrategy.s.sol ├── TestStrategyVault.s.sol ├── UltraLRT.s.sol ├── config.json └── upgrades │ ├── StrategyVaultV2.s.sol │ ├── TwoAssetBasket.s.sol │ └── VaultV2.s.sol ├── scripts ├── deploy.ts ├── doc-gen │ ├── contract.hbs │ ├── gen-test-doc.ts │ └── page.hbs ├── fork.ts └── utils │ ├── constants │ ├── blockchain.ts │ └── types.ts │ ├── defender-client.ts │ ├── export.ts │ ├── get-bytes.ts │ ├── types.ts │ └── wormhole.ts ├── slither.config.json ├── src ├── incentives │ ├── AffineGenesis.sol │ ├── AffinePass.sol │ └── AffinePassBridge.sol ├── interfaces │ ├── AggregatorV3Interface.sol │ ├── Beefy.sol │ ├── ICreate3Factory.sol │ ├── IERC4626.sol │ ├── IPearl.sol │ ├── IRootChainManager.sol │ ├── IUniPositionValue.sol │ ├── IWETH.sol │ ├── IWormhole.sol │ ├── aave.sol │ ├── aave │ │ ├── DataTypes.sol │ │ ├── IAToken.sol │ │ ├── IAaveIncentivesController.sol │ │ ├── IInitializableAToken.sol │ │ ├── ILendingPool.sol │ │ ├── ILendingPoolAddressesProvider.sol │ │ ├── ILendingPoolAddressesProviderRegistry.sol │ │ ├── IProtocolDataProvider.sol │ │ └── IScaledBalanceToken.sol │ ├── aerodrome.sol │ ├── aerodrome │ │ ├── IAeroPool.sol │ │ └── IAeroRouter.sol │ ├── balancer.sol │ ├── balancer │ │ ├── IBalancerQueries.sol │ │ ├── IBalancerVault.sol │ │ └── IFlashLoanRecipient.sol │ ├── compound.sol │ ├── compound │ │ ├── ICToken.sol │ │ ├── IComet.sol │ │ ├── IComptroller.sol │ │ └── IRewards.sol │ ├── convex.sol │ ├── convex │ │ ├── IConvexBooster.sol │ │ └── IConvexRewards.sol │ ├── curve.sol │ ├── curve │ │ ├── ICurvePool.sol │ │ ├── ILiquidityGauge.sol │ │ ├── IMetaPoolZap.sol │ │ └── IMinter.sol │ ├── eigenlayer │ │ └── eigen.sol │ ├── lido │ │ ├── IStEth.sol │ │ └── IWSTETH.sol │ ├── maker.sol │ ├── maker │ │ ├── ICdpManager.sol │ │ ├── IGemJoin.sol │ │ ├── IMakerAdapter.sol │ │ └── IVat.sol │ ├── pearl │ │ ├── IPair.sol │ │ └── IRouter.sol │ ├── permit2 │ │ ├── IAllowanceTransfer.sol │ │ ├── IEIP712.sol │ │ ├── IPermit2.sol │ │ └── ISignatureTransfer.sol │ ├── stader │ │ └── IChildPool.sol │ ├── sushiswap │ │ └── IMasterChef.sol │ └── symbiotic │ │ ├── ICollateral.sol │ │ └── IDefaultCollateral.sol ├── libs │ ├── ReStakingErrors.sol │ ├── VaultErrors.sol │ └── audited │ │ ├── Constants.sol │ │ ├── DollarMath.sol │ │ ├── SlippageUtils.sol │ │ └── Unchecked.sol ├── strategies │ ├── AaveV3Strategy.sol │ ├── AccessStrategy.sol │ ├── BeefyAeroStrategy.sol │ ├── BeefyEpochStrategy.sol │ ├── BeefyPearlStrategy.sol │ ├── BeefyStrategy.sol │ ├── CompoundV3Strategy.sol │ ├── ConvexStrategy.sol │ ├── DeltaNeutralLp.sol │ ├── DeltaNeutralLpV3.sol │ ├── L1CompoundStrategy.sol │ ├── LevMaticXLoopStrategy.sol │ ├── LidoLev.sol │ ├── LidoLevL2.sol │ ├── LidoLevV3.sol │ ├── SSVDeltaNeutralLp.sol │ ├── StaderLevMaticStrategy.sol │ ├── StrikeEthStrategy.sol │ ├── audited │ │ ├── AaveV2Strategy.sol │ │ └── BaseStrategy.sol │ └── deployed │ │ └── LidoLevEthStrategy.sol ├── test │ ├── AaveV2Strategy.t.sol │ ├── AaveV3Strategy.t.sol │ ├── AffineReStaking.t.sol │ ├── BaseStrategy.t.sol │ ├── BaseVault.t.sol │ ├── BeefyAeroStrategy.t.sol │ ├── BeefyEpochStrategy.t.sol │ ├── BeefyPearlEpochStrategy.t.sol │ ├── BeefyPearlStrategy.t.sol │ ├── BeefyStrategy.t.sol │ ├── BridgeEscrow.t.sol │ ├── CREATE3Factory.sol │ ├── CommonVault.t.sol │ ├── CompoundV3Strategy.t.sol │ ├── ConvertLib.sol │ ├── ConvexStrategy.t.sol │ ├── Create3Deployer.sol │ ├── DelegatorFactory.t.sol │ ├── DeltaNeutralLp.t.sol │ ├── DeltaNeutralLpV3.t.sol │ ├── Deploy.sol │ ├── EigenDelegator.t.sol │ ├── EmergencyWithdrawalQueue.t.sol │ ├── EthVault.t.sol │ ├── Forwarder.t.sol │ ├── L1CompoundStrategy.t.sol │ ├── L1Vault.t.sol │ ├── L2Vault.t.sol │ ├── L2VaultV2.t.sol │ ├── LevMaticXLoopStrategy.t.sol │ ├── LidoLev.t.sol │ ├── LidoLevL2.t.sol │ ├── LidoLevV3.t.sol │ ├── LockedWithdrawal.t.sol │ ├── Router.t.sol │ ├── SSVDeltaNeutralLp.t.sol │ ├── SmartWallet.t.sol │ ├── StaderLevMatic.t.sol │ ├── StrategyVault.t.sol │ ├── StrikeEthStrategy.t.sol │ ├── SymbitoicDelegator.t.sol │ ├── TestPlus.sol │ ├── TwoAssetBasket.t.sol │ ├── UltraLRT.t.sol │ ├── UltraLRTRouter.t.sol │ ├── Vault.t.sol │ ├── WithdrawalEscrow.t.sol │ ├── WithdrawalEscrowV2.t.sol │ ├── Wormhole.t.sol │ ├── integration │ │ ├── L2Vault.int.sol │ │ ├── L2VaultV2.int.sol │ │ ├── SSVDeltaNeutral.int.sol │ │ ├── Storage.int.sol │ │ ├── StrategyVaultV2.int.sol │ │ ├── TearDown.int.sol │ │ ├── TwoAssetBasket.int.sol │ │ └── VaultV2.int.sol │ └── mocks │ │ ├── MockERC20.sol │ │ ├── SymCollateral.sol │ │ ├── TestStrategy.sol │ │ ├── foo.js │ │ └── index.sol ├── testnet │ ├── DummyEpochStrategy.sol │ ├── MockERC20.sol │ └── MockEpochStrategy.sol ├── utils │ ├── ReentrancyGuard.sol │ ├── SmartWallet.sol │ └── audited │ │ ├── AffineGovernable.sol │ │ └── Detailed.sol └── vaults │ ├── AffineVault.sol │ ├── EthVault.sol │ ├── EthVaultV2.sol │ ├── HarvestStorage.sol │ ├── LockedWithdrawal.sol │ ├── NftGate.sol │ ├── TwoAssetBasket.sol │ ├── Vault.sol │ ├── VaultV2.sol │ ├── cross-chain-vault │ ├── DummyRelay.sol │ ├── L2VaultV2.sol │ ├── RebalanceModule.sol │ ├── RebalanceStorage.sol │ ├── audited │ │ ├── BaseVault.sol │ │ ├── EmergencyWithdrawalQueue.sol │ │ ├── Forwarder.sol │ │ ├── L1Vault.sol │ │ └── L2Vault.sol │ ├── escrow │ │ └── audited │ │ │ ├── BridgeEscrow.sol │ │ │ ├── L1BridgeEscrow.sol │ │ │ └── L2BridgeEscrow.sol │ ├── router │ │ └── audited │ │ │ ├── ERC4626Router.sol │ │ │ ├── ERC4626RouterBase.sol │ │ │ └── Router.sol │ └── wormhole │ │ └── audited │ │ ├── L1WormholeRouter.sol │ │ ├── L2WormholeRouter.sol │ │ └── WormholeRouter.sol │ ├── custom │ ├── DegenEthVault.sol │ ├── DegenVault.sol │ ├── DegenVaultV2.sol │ └── L2USDEarnVault.sol │ ├── locked │ ├── BaseStrategyVault.sol │ ├── StrategyVault.sol │ ├── StrategyVaultV2.sol │ └── WithdrawalEscrow.sol │ └── restaking │ ├── AffineDelegator.sol │ ├── AffineReStaking.sol │ ├── DelegatorBeacon.sol │ ├── DelegatorFactory.sol │ ├── EigenDelegator.sol │ ├── IDelegator.sol │ ├── README.md │ ├── RestakingTechnicalDocs.md │ ├── SymDelegatorFactory.sol │ ├── SymbioticDelegator.sol │ ├── UltraLRT.sol │ ├── UltraLRTRouter.sol │ ├── UltraLRTStorage.sol │ ├── WithdrawalEscrowV2.sol │ └── affine ultraETH fundflow.png ├── tasks ├── accounts.ts └── unblock.ts ├── tsconfig.json └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | MNEMONIC=<12 word mnemonic phrase> 2 | REPORT_GAS= 3 | ALCHEMY_ETH_GOERLI_KEY= 4 | ALCHEMY_POLYGON_MUMBAI_KEY= 5 | ALCHEMY_ETH_MAINNET_KEY= 6 | ALCHEMY_POLYGON_MAINNET_KEY= 7 | ETHERSCAN_API_KEY= 8 | POLYGONSCAN_API_KEY= 9 | DEFENDER_API_KEY= 10 | DEFENDER_API_SECRET= 11 | 12 | # Needed for Rebalancer and QueueBot only 13 | CONTRACT_VERSION= 14 | 15 | # Needed for running testnet Reblanacer and Queuebot 16 | GOERLI_DEFENDER_RELAYER_API_KEY= 17 | GOERLI_DEFENDER_RELAYER_API_SECRET= 18 | MUMBAI_DEFENDER_RELAYER_API_KEY= 19 | MUMBAI_DEFENDER_RELAYER_API_SECRET= 20 | 21 | # Needed for running mainnet Reblanacer and Queuebot 22 | ETH_MAINNET_DEFENDER_RELAYER_API_KEY= 23 | ETH_MAINNET_DEFENDER_RELAYER_API_SECRET= 24 | POLYGON_MAINNET_DEFENDER_RELAYER_API_KEY= 25 | POLYGON_MAINNET_DEFENDER_RELAYER_API_SECRET= -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This file outlines people who will automatically be added as reviewers to PRs 2 | * @dstack 3 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Upload artifacts to S3 bucket when a new release is started. 2 | name: Release Workflow Testnet 3 | 4 | # Triggers the workflow on push of a release tag 5 | on: 6 | # Allows you to run this workflow manually from the Actions tab 7 | workflow_dispatch: 8 | 9 | jobs: 10 | workflow: 11 | name: Deploy contracts then upload generated ABIs and AddressBook to S3 bucket. 12 | runs-on: ubuntu-latest 13 | env: 14 | # S3 sync env variables 15 | AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} 16 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 17 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 18 | AWS_REGION: "us-east-2" 19 | # Hardhat env variables 20 | MNEMONIC: ${{ secrets.MNEMONIC_TESTNET }} 21 | ALCHEMY_ETH_GOERLI_KEY: ${{ secrets.ALCHEMY_ETH_GOERLI_KEY }} 22 | ALCHEMY_POLYGON_MUMBAI_KEY: ${{ secrets.ALCHEMY_POLYGON_MUMBAI_KEY }} 23 | ALCHEMY_ETH_MAINNET_KEY: ${{ secrets.ALCHEMY_ETH_MAINNET_KEY }} 24 | ALCHEMY_POLYGON_MAINNET_KEY: ${{ secrets.ALCHEMY_POLYGON_MAINNET_KEY }} 25 | DEFENDER_API_KEY: ${{ secrets.DEFENDER_API_KEY }} 26 | DEFENDER_API_SECRET: ${{ secrets.DEFENDER_API_SECRET }} 27 | steps: 28 | - name: Checkout 29 | uses: actions/checkout@v2 30 | 31 | - name: Use Node.js 32 | uses: actions/setup-node@v1 33 | with: 34 | node-version: "16.x" 35 | 36 | - name: Install Foundry 37 | uses: onbjerg/foundry-toolchain@v1 38 | with: 39 | version: nightly 40 | 41 | - name: Install yarn dependencies, and compile contracts 42 | run: yarn --frozen-lockfile && yarn build 43 | 44 | - name: Run deployment scripts 45 | run: yarn ts-node scripts/deploy.ts -l 1 -t -b && yarn ts-node scripts/deploy.ts -l 2 -t -b 46 | 47 | - name: Uploading addressbook to S3 bucket in version specific subdirectory 48 | uses: jakejarvis/s3-sync-action@master 49 | with: 50 | args: --follow-symlinks --delete --exclude '*' --include 'addressbook.json' 51 | env: 52 | DEST_DIR: "test" 53 | -------------------------------------------------------------------------------- /.github/workflows/release_prod.yml: -------------------------------------------------------------------------------- 1 | # Upload artifacts to S3 bucket when a new release is started. 2 | name: Release Workflow 3 | 4 | # Triggers the workflow on push of a release tag 5 | on: 6 | release: 7 | types: [published] 8 | branches: [mainnet-beta-audited] 9 | 10 | # Allows you to run this workflow manually from the Actions tab 11 | workflow_dispatch: 12 | 13 | jobs: 14 | workflow: 15 | name: Deploy contracts then upload generated ABIs and AddressBook to S3 bucket. 16 | runs-on: ubuntu-latest 17 | env: 18 | # S3 sync env variables 19 | AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} 20 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 21 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 22 | AWS_REGION: "us-east-2" 23 | VERSION: ${{ github.event.release.tag_name }} 24 | # Hardhat env variables 25 | MNEMONIC: ${{ secrets.MNEMONIC }} 26 | ALCHEMY_ETH_GOERLI_KEY: ${{ secrets.ALCHEMY_ETH_GOERLI_KEY }} 27 | ALCHEMY_POLYGON_MUMBAI_KEY: ${{ secrets.ALCHEMY_POLYGON_MUMBAI_KEY }} 28 | ALCHEMY_ETH_MAINNET_KEY: ${{ secrets.ALCHEMY_ETH_MAINNET_KEY }} 29 | ALCHEMY_POLYGON_MAINNET_KEY: ${{ secrets.ALCHEMY_POLYGON_MAINNET_KEY }} 30 | DEFENDER_API_KEY: ${{ secrets.DEFENDER_API_KEY }} 31 | DEFENDER_API_SECRET: ${{ secrets.DEFENDER_API_SECRET }} 32 | steps: 33 | - name: Checkout 34 | uses: actions/checkout@v2 35 | 36 | - name: Use Node.js 37 | uses: actions/setup-node@v1 38 | with: 39 | node-version: "16.x" 40 | 41 | - name: Install Foundry 42 | uses: onbjerg/foundry-toolchain@v1 43 | with: 44 | version: nightly 45 | 46 | - name: Install yarn dependencies, and compile contracts 47 | run: yarn --frozen-lockfile && yarn build 48 | 49 | - name: Run deployment scripts 50 | run: yarn ts-node scripts/deploy.ts -l 1 -b && yarn ts-node scripts/deploy.ts -l 2 -b 51 | 52 | - name: Uploading addressbook to S3 bucket in version specific subdirectory 53 | uses: jakejarvis/s3-sync-action@master 54 | with: 55 | args: --follow-symlinks --delete --exclude '*' --include 'addressbook.json' 56 | env: 57 | DEST_DIR: ${{ env.VERSION }} 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | yarn-error.log 4 | .env 5 | 6 | 7 | #Hardhat files 8 | artifacts 9 | typechain 10 | hh-cache 11 | .openzeppelin/unknown-*.json 12 | 13 | # Foundry 14 | out 15 | cache 16 | lcov.info 17 | broadcast 18 | *.salt 19 | coverage/ 20 | 21 | # Address Book 22 | addressbook.json 23 | 24 | # Other 25 | .DS_Store 26 | 27 | # Openzeppelin 28 | # Note: Not needed in testing phase, but in prod, probably 29 | # worth keeping openzep files in VCS. 30 | .openzeppelin -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | yarn lint 5 | yarn format:fix 6 | yarn snap 7 | yarn build-hh && yarn tsc 8 | git add --all 9 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.9.1 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | export/ 2 | deployments/ 3 | artifacts/ 4 | cache/ 5 | coverage/ 6 | node_modules/ 7 | package.json 8 | typechain/ 9 | dist/ 10 | src/ 11 | *.sol -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": true, 4 | "endOfLine":"auto", 5 | "printWidth": 120, 6 | "singleQuote": false, 7 | "tabWidth": 2, 8 | "trailingComma": "all", 9 | "overrides": [ 10 | { 11 | "files": "*.sol", 12 | "options": { 13 | "tabWidth": 4 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "max-line-length": "off", 5 | "compiler-version": ["error", "^0.8.0"], 6 | "state-visibility": "off", 7 | "not-rely-on-time": "off", 8 | "no-empty-blocks": "off", 9 | "func-visibility": ["warn", { "ignoreConstructors": true }], 10 | "no-unused-vars": "error" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | export/ 2 | deployments/ 3 | artifacts/ 4 | cache/ 5 | coverage/ 6 | node_modules/ 7 | typechain/ 8 | src/test 9 | src/testnet 10 | src/external/Multicall.sol -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["juanblanco.solidity", "esbenp.prettier-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.rulers": [120], 3 | "editor.formatOnSave": true, 4 | "editor.defaultFormatter": "esbenp.prettier-vscode", 5 | "solidity.packageDefaultDependenciesContractsDirectory": "", 6 | "solidity.packageDefaultDependenciesDirectory": "node_modules", 7 | "solidity.compileUsingRemoteVersion": "v0.8.16", 8 | "[handlebars]": { 9 | "editor.formatOnSave": false, 10 | "editor.formatOnPaste": false 11 | }, 12 | "[markdown]": { 13 | "editor.formatOnSave": false, 14 | "editor.formatOnPaste": false, 15 | "editor.wordWrap": "wordWrapColumn", 16 | "editor.wordWrapColumn": 512 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /abi/AffineDelegator.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "asset", 5 | "outputs": [ 6 | { 7 | "internalType": "contract ERC20", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [ 17 | { 18 | "internalType": "uint256", 19 | "name": "amount", 20 | "type": "uint256" 21 | } 22 | ], 23 | "name": "delegate", 24 | "outputs": [], 25 | "stateMutability": "nonpayable", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [], 30 | "name": "queuedAssets", 31 | "outputs": [ 32 | { 33 | "internalType": "uint256", 34 | "name": "", 35 | "type": "uint256" 36 | } 37 | ], 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [ 43 | { 44 | "internalType": "uint256", 45 | "name": "assets", 46 | "type": "uint256" 47 | } 48 | ], 49 | "name": "requestWithdrawal", 50 | "outputs": [], 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | }, 54 | { 55 | "inputs": [], 56 | "name": "totalLockedValue", 57 | "outputs": [ 58 | { 59 | "internalType": "uint256", 60 | "name": "", 61 | "type": "uint256" 62 | } 63 | ], 64 | "stateMutability": "view", 65 | "type": "function" 66 | }, 67 | { 68 | "inputs": [], 69 | "name": "vault", 70 | "outputs": [ 71 | { 72 | "internalType": "address", 73 | "name": "", 74 | "type": "address" 75 | } 76 | ], 77 | "stateMutability": "view", 78 | "type": "function" 79 | }, 80 | { 81 | "inputs": [], 82 | "name": "withdraw", 83 | "outputs": [], 84 | "stateMutability": "nonpayable", 85 | "type": "function" 86 | }, 87 | { 88 | "inputs": [], 89 | "name": "withdrawableAssets", 90 | "outputs": [ 91 | { 92 | "internalType": "uint256", 93 | "name": "", 94 | "type": "uint256" 95 | } 96 | ], 97 | "stateMutability": "view", 98 | "type": "function" 99 | } 100 | ] 101 | -------------------------------------------------------------------------------- /abi/AffineGovernable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "governance", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/BaseStrategy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "asset", 5 | "outputs": [ 6 | { 7 | "internalType": "contract ERC20", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "balanceOfAsset", 18 | "outputs": [ 19 | { 20 | "internalType": "uint256", 21 | "name": "assets", 22 | "type": "uint256" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [ 30 | { 31 | "internalType": "uint256", 32 | "name": "amount", 33 | "type": "uint256" 34 | } 35 | ], 36 | "name": "divest", 37 | "outputs": [ 38 | { 39 | "internalType": "uint256", 40 | "name": "", 41 | "type": "uint256" 42 | } 43 | ], 44 | "stateMutability": "nonpayable", 45 | "type": "function" 46 | }, 47 | { 48 | "inputs": [ 49 | { 50 | "internalType": "uint256", 51 | "name": "amount", 52 | "type": "uint256" 53 | } 54 | ], 55 | "name": "invest", 56 | "outputs": [], 57 | "stateMutability": "nonpayable", 58 | "type": "function" 59 | }, 60 | { 61 | "inputs": [ 62 | { 63 | "internalType": "contract ERC20", 64 | "name": "token", 65 | "type": "address" 66 | } 67 | ], 68 | "name": "sweep", 69 | "outputs": [], 70 | "stateMutability": "nonpayable", 71 | "type": "function" 72 | }, 73 | { 74 | "inputs": [], 75 | "name": "totalLockedValue", 76 | "outputs": [ 77 | { 78 | "internalType": "uint256", 79 | "name": "", 80 | "type": "uint256" 81 | } 82 | ], 83 | "stateMutability": "nonpayable", 84 | "type": "function" 85 | }, 86 | { 87 | "inputs": [], 88 | "name": "vault", 89 | "outputs": [ 90 | { 91 | "internalType": "contract AffineVault", 92 | "name": "", 93 | "type": "address" 94 | } 95 | ], 96 | "stateMutability": "view", 97 | "type": "function" 98 | } 99 | ] 100 | -------------------------------------------------------------------------------- /abi/BeaconProxy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "beacon", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "bytes", 11 | "name": "data", 12 | "type": "bytes" 13 | } 14 | ], 15 | "stateMutability": "payable", 16 | "type": "constructor" 17 | }, 18 | { 19 | "anonymous": false, 20 | "inputs": [ 21 | { 22 | "indexed": false, 23 | "internalType": "address", 24 | "name": "previousAdmin", 25 | "type": "address" 26 | }, 27 | { 28 | "indexed": false, 29 | "internalType": "address", 30 | "name": "newAdmin", 31 | "type": "address" 32 | } 33 | ], 34 | "name": "AdminChanged", 35 | "type": "event" 36 | }, 37 | { 38 | "anonymous": false, 39 | "inputs": [ 40 | { 41 | "indexed": true, 42 | "internalType": "address", 43 | "name": "beacon", 44 | "type": "address" 45 | } 46 | ], 47 | "name": "BeaconUpgraded", 48 | "type": "event" 49 | }, 50 | { 51 | "anonymous": false, 52 | "inputs": [ 53 | { 54 | "indexed": true, 55 | "internalType": "address", 56 | "name": "implementation", 57 | "type": "address" 58 | } 59 | ], 60 | "name": "Upgraded", 61 | "type": "event" 62 | }, 63 | { 64 | "stateMutability": "payable", 65 | "type": "fallback" 66 | }, 67 | { 68 | "stateMutability": "payable", 69 | "type": "receive" 70 | } 71 | ] 72 | -------------------------------------------------------------------------------- /abi/BridgeEscrow.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint256", 8 | "name": "assets", 9 | "type": "uint256" 10 | } 11 | ], 12 | "name": "TransferToVault", 13 | "type": "event" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "asset", 18 | "outputs": [ 19 | { 20 | "internalType": "contract ERC20", 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [ 30 | { 31 | "internalType": "uint256", 32 | "name": "assets", 33 | "type": "uint256" 34 | }, 35 | { 36 | "internalType": "bytes", 37 | "name": "exitProof", 38 | "type": "bytes" 39 | } 40 | ], 41 | "name": "clearFunds", 42 | "outputs": [], 43 | "stateMutability": "nonpayable", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "name": "governance", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [ 61 | { 62 | "internalType": "uint256", 63 | "name": "amount", 64 | "type": "uint256" 65 | }, 66 | { 67 | "internalType": "bytes", 68 | "name": "exitProof", 69 | "type": "bytes" 70 | } 71 | ], 72 | "name": "rescueFunds", 73 | "outputs": [], 74 | "stateMutability": "nonpayable", 75 | "type": "function" 76 | }, 77 | { 78 | "inputs": [], 79 | "name": "wormholeRouter", 80 | "outputs": [ 81 | { 82 | "internalType": "address", 83 | "name": "", 84 | "type": "address" 85 | } 86 | ], 87 | "stateMutability": "view", 88 | "type": "function" 89 | } 90 | ] 91 | -------------------------------------------------------------------------------- /abi/Client.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "EVM_EXTRA_ARGS_V1_TAG", 5 | "outputs": [ 6 | { 7 | "internalType": "bytes4", 8 | "name": "", 9 | "type": "bytes4" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/ContextUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint8", 8 | "name": "version", 9 | "type": "uint8" 10 | } 11 | ], 12 | "name": "Initialized", 13 | "type": "event" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/DelegatorFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_vault", 7 | "type": "address" 8 | } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [ 15 | { 16 | "internalType": "address", 17 | "name": "_operator", 18 | "type": "address" 19 | } 20 | ], 21 | "name": "createDelegator", 22 | "outputs": [ 23 | { 24 | "internalType": "address", 25 | "name": "", 26 | "type": "address" 27 | } 28 | ], 29 | "stateMutability": "nonpayable", 30 | "type": "function" 31 | }, 32 | { 33 | "inputs": [], 34 | "name": "vault", 35 | "outputs": [ 36 | { 37 | "internalType": "address", 38 | "name": "", 39 | "type": "address" 40 | } 41 | ], 42 | "stateMutability": "view", 43 | "type": "function" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /abi/DetailedShare.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "detailedPrice", 5 | "outputs": [ 6 | { 7 | "components": [ 8 | { 9 | "internalType": "uint256", 10 | "name": "num", 11 | "type": "uint256" 12 | }, 13 | { 14 | "internalType": "uint8", 15 | "name": "decimals", 16 | "type": "uint8" 17 | } 18 | ], 19 | "internalType": "struct DetailedShare.Number", 20 | "name": "", 21 | "type": "tuple" 22 | } 23 | ], 24 | "stateMutability": "nonpayable", 25 | "type": "function" 26 | }, 27 | { 28 | "inputs": [], 29 | "name": "detailedTVL", 30 | "outputs": [ 31 | { 32 | "components": [ 33 | { 34 | "internalType": "uint256", 35 | "name": "num", 36 | "type": "uint256" 37 | }, 38 | { 39 | "internalType": "uint8", 40 | "name": "decimals", 41 | "type": "uint8" 42 | } 43 | ], 44 | "internalType": "struct DetailedShare.Number", 45 | "name": "", 46 | "type": "tuple" 47 | } 48 | ], 49 | "stateMutability": "nonpayable", 50 | "type": "function" 51 | }, 52 | { 53 | "inputs": [], 54 | "name": "detailedTotalSupply", 55 | "outputs": [ 56 | { 57 | "components": [ 58 | { 59 | "internalType": "uint256", 60 | "name": "num", 61 | "type": "uint256" 62 | }, 63 | { 64 | "internalType": "uint8", 65 | "name": "decimals", 66 | "type": "uint8" 67 | } 68 | ], 69 | "internalType": "struct DetailedShare.Number", 70 | "name": "", 71 | "type": "tuple" 72 | } 73 | ], 74 | "stateMutability": "nonpayable", 75 | "type": "function" 76 | } 77 | ] 78 | -------------------------------------------------------------------------------- /abi/DummyRelay.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "trustedForwarder", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/ERC165.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "bytes4", 6 | "name": "interfaceId", 7 | "type": "bytes4" 8 | } 9 | ], 10 | "name": "supportsInterface", 11 | "outputs": [ 12 | { 13 | "internalType": "bool", 14 | "name": "", 15 | "type": "bool" 16 | } 17 | ], 18 | "stateMutability": "view", 19 | "type": "function" 20 | } 21 | ] 22 | -------------------------------------------------------------------------------- /abi/ERC165Upgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint8", 8 | "name": "version", 9 | "type": "uint8" 10 | } 11 | ], 12 | "name": "Initialized", 13 | "type": "event" 14 | }, 15 | { 16 | "inputs": [ 17 | { 18 | "internalType": "bytes4", 19 | "name": "interfaceId", 20 | "type": "bytes4" 21 | } 22 | ], 23 | "name": "supportsInterface", 24 | "outputs": [ 25 | { 26 | "internalType": "bool", 27 | "name": "", 28 | "type": "bool" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /abi/ERC1967Upgrade.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "address", 8 | "name": "previousAdmin", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": false, 13 | "internalType": "address", 14 | "name": "newAdmin", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "AdminChanged", 19 | "type": "event" 20 | }, 21 | { 22 | "anonymous": false, 23 | "inputs": [ 24 | { 25 | "indexed": true, 26 | "internalType": "address", 27 | "name": "beacon", 28 | "type": "address" 29 | } 30 | ], 31 | "name": "BeaconUpgraded", 32 | "type": "event" 33 | }, 34 | { 35 | "anonymous": false, 36 | "inputs": [ 37 | { 38 | "indexed": true, 39 | "internalType": "address", 40 | "name": "implementation", 41 | "type": "address" 42 | } 43 | ], 44 | "name": "Upgraded", 45 | "type": "event" 46 | } 47 | ] 48 | -------------------------------------------------------------------------------- /abi/ERC1967UpgradeUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "address", 8 | "name": "previousAdmin", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": false, 13 | "internalType": "address", 14 | "name": "newAdmin", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "AdminChanged", 19 | "type": "event" 20 | }, 21 | { 22 | "anonymous": false, 23 | "inputs": [ 24 | { 25 | "indexed": true, 26 | "internalType": "address", 27 | "name": "beacon", 28 | "type": "address" 29 | } 30 | ], 31 | "name": "BeaconUpgraded", 32 | "type": "event" 33 | }, 34 | { 35 | "anonymous": false, 36 | "inputs": [ 37 | { 38 | "indexed": false, 39 | "internalType": "uint8", 40 | "name": "version", 41 | "type": "uint8" 42 | } 43 | ], 44 | "name": "Initialized", 45 | "type": "event" 46 | }, 47 | { 48 | "anonymous": false, 49 | "inputs": [ 50 | { 51 | "indexed": true, 52 | "internalType": "address", 53 | "name": "implementation", 54 | "type": "address" 55 | } 56 | ], 57 | "name": "Upgraded", 58 | "type": "event" 59 | } 60 | ] 61 | -------------------------------------------------------------------------------- /abi/ERC721A__IERC721Receiver.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "operator", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "from", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "uint256", 16 | "name": "tokenId", 17 | "type": "uint256" 18 | }, 19 | { 20 | "internalType": "bytes", 21 | "name": "data", 22 | "type": "bytes" 23 | } 24 | ], 25 | "name": "onERC721Received", 26 | "outputs": [ 27 | { 28 | "internalType": "bytes4", 29 | "name": "", 30 | "type": "bytes4" 31 | } 32 | ], 33 | "stateMutability": "nonpayable", 34 | "type": "function" 35 | } 36 | ] 37 | -------------------------------------------------------------------------------- /abi/ERC721TokenReceiver.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "uint256", 16 | "name": "", 17 | "type": "uint256" 18 | }, 19 | { 20 | "internalType": "bytes", 21 | "name": "", 22 | "type": "bytes" 23 | } 24 | ], 25 | "name": "onERC721Received", 26 | "outputs": [ 27 | { 28 | "internalType": "bytes4", 29 | "name": "", 30 | "type": "bytes4" 31 | } 32 | ], 33 | "stateMutability": "nonpayable", 34 | "type": "function" 35 | } 36 | ] 37 | -------------------------------------------------------------------------------- /abi/HarvestStorage.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint256", 8 | "name": "amount", 9 | "type": "uint256" 10 | } 11 | ], 12 | "name": "PerformanceFeeWithdrawn", 13 | "type": "event" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "accumulatedPerformanceFee", 18 | "outputs": [ 19 | { 20 | "internalType": "uint128", 21 | "name": "", 22 | "type": "uint128" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [], 30 | "name": "governance", 31 | "outputs": [ 32 | { 33 | "internalType": "address", 34 | "name": "", 35 | "type": "address" 36 | } 37 | ], 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "performanceFeeBps", 44 | "outputs": [ 45 | { 46 | "internalType": "uint128", 47 | "name": "", 48 | "type": "uint128" 49 | } 50 | ], 51 | "stateMutability": "view", 52 | "type": "function" 53 | }, 54 | { 55 | "inputs": [ 56 | { 57 | "internalType": "uint128", 58 | "name": "_newFeeBps", 59 | "type": "uint128" 60 | } 61 | ], 62 | "name": "setPerformanceFeeBps", 63 | "outputs": [], 64 | "stateMutability": "nonpayable", 65 | "type": "function" 66 | } 67 | ] 68 | -------------------------------------------------------------------------------- /abi/IAny2EVMMessageReceiver.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "components": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "messageId", 9 | "type": "bytes32" 10 | }, 11 | { 12 | "internalType": "uint64", 13 | "name": "sourceChainSelector", 14 | "type": "uint64" 15 | }, 16 | { 17 | "internalType": "bytes", 18 | "name": "sender", 19 | "type": "bytes" 20 | }, 21 | { 22 | "internalType": "bytes", 23 | "name": "data", 24 | "type": "bytes" 25 | }, 26 | { 27 | "components": [ 28 | { 29 | "internalType": "address", 30 | "name": "token", 31 | "type": "address" 32 | }, 33 | { 34 | "internalType": "uint256", 35 | "name": "amount", 36 | "type": "uint256" 37 | } 38 | ], 39 | "internalType": "struct Client.EVMTokenAmount[]", 40 | "name": "destTokenAmounts", 41 | "type": "tuple[]" 42 | } 43 | ], 44 | "internalType": "struct Client.Any2EVMMessage", 45 | "name": "message", 46 | "type": "tuple" 47 | } 48 | ], 49 | "name": "ccipReceive", 50 | "outputs": [], 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | } 54 | ] 55 | -------------------------------------------------------------------------------- /abi/IBalancerQueries.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "components": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "poolId", 9 | "type": "bytes32" 10 | }, 11 | { 12 | "internalType": "enum IBalancerVault.SwapKind", 13 | "name": "kind", 14 | "type": "uint8" 15 | }, 16 | { 17 | "internalType": "address", 18 | "name": "assetIn", 19 | "type": "address" 20 | }, 21 | { 22 | "internalType": "address", 23 | "name": "assetOut", 24 | "type": "address" 25 | }, 26 | { 27 | "internalType": "uint256", 28 | "name": "amount", 29 | "type": "uint256" 30 | }, 31 | { 32 | "internalType": "bytes", 33 | "name": "userData", 34 | "type": "bytes" 35 | } 36 | ], 37 | "internalType": "struct IBalancerVault.SingleSwap", 38 | "name": "singleSwap", 39 | "type": "tuple" 40 | }, 41 | { 42 | "components": [ 43 | { 44 | "internalType": "address", 45 | "name": "sender", 46 | "type": "address" 47 | }, 48 | { 49 | "internalType": "bool", 50 | "name": "fromInternalBalance", 51 | "type": "bool" 52 | }, 53 | { 54 | "internalType": "address payable", 55 | "name": "recipient", 56 | "type": "address" 57 | }, 58 | { 59 | "internalType": "bool", 60 | "name": "toInternalBalance", 61 | "type": "bool" 62 | } 63 | ], 64 | "internalType": "struct IBalancerVault.FundManagement", 65 | "name": "funds", 66 | "type": "tuple" 67 | } 68 | ], 69 | "name": "querySwap", 70 | "outputs": [ 71 | { 72 | "internalType": "uint256", 73 | "name": "", 74 | "type": "uint256" 75 | } 76 | ], 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | } 80 | ] 81 | -------------------------------------------------------------------------------- /abi/IBeacon.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "implementation", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/IBeaconUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "implementation", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/ICREATE3Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "bytes32", 6 | "name": "salt", 7 | "type": "bytes32" 8 | }, 9 | { 10 | "internalType": "bytes", 11 | "name": "creationCode", 12 | "type": "bytes" 13 | } 14 | ], 15 | "name": "deploy", 16 | "outputs": [ 17 | { 18 | "internalType": "address", 19 | "name": "deployed", 20 | "type": "address" 21 | } 22 | ], 23 | "stateMutability": "payable", 24 | "type": "function" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "address", 30 | "name": "deployer", 31 | "type": "address" 32 | }, 33 | { 34 | "internalType": "bytes32", 35 | "name": "salt", 36 | "type": "bytes32" 37 | } 38 | ], 39 | "name": "getDeployed", 40 | "outputs": [ 41 | { 42 | "internalType": "address", 43 | "name": "deployed", 44 | "type": "address" 45 | } 46 | ], 47 | "stateMutability": "view", 48 | "type": "function" 49 | } 50 | ] 51 | -------------------------------------------------------------------------------- /abi/IChildERC20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "uint256", 6 | "name": "amount", 7 | "type": "uint256" 8 | } 9 | ], 10 | "name": "withdraw", 11 | "outputs": [], 12 | "stateMutability": "nonpayable", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/IDelegator.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "uint256", 6 | "name": "assets", 7 | "type": "uint256" 8 | } 9 | ], 10 | "name": "checkAssetAvailability", 11 | "outputs": [ 12 | { 13 | "internalType": "bool", 14 | "name": "", 15 | "type": "bool" 16 | } 17 | ], 18 | "stateMutability": "view", 19 | "type": "function" 20 | }, 21 | { 22 | "inputs": [ 23 | { 24 | "internalType": "uint256", 25 | "name": "amount", 26 | "type": "uint256" 27 | } 28 | ], 29 | "name": "delegate", 30 | "outputs": [], 31 | "stateMutability": "nonpayable", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [], 36 | "name": "queuedAssets", 37 | "outputs": [ 38 | { 39 | "internalType": "uint256", 40 | "name": "", 41 | "type": "uint256" 42 | } 43 | ], 44 | "stateMutability": "view", 45 | "type": "function" 46 | }, 47 | { 48 | "inputs": [ 49 | { 50 | "internalType": "uint256", 51 | "name": "assets", 52 | "type": "uint256" 53 | } 54 | ], 55 | "name": "requestWithdrawal", 56 | "outputs": [], 57 | "stateMutability": "nonpayable", 58 | "type": "function" 59 | }, 60 | { 61 | "inputs": [], 62 | "name": "totalLockedValue", 63 | "outputs": [ 64 | { 65 | "internalType": "uint256", 66 | "name": "", 67 | "type": "uint256" 68 | } 69 | ], 70 | "stateMutability": "nonpayable", 71 | "type": "function" 72 | }, 73 | { 74 | "inputs": [], 75 | "name": "withdraw", 76 | "outputs": [], 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "inputs": [], 82 | "name": "withdrawableAssets", 83 | "outputs": [ 84 | { 85 | "internalType": "uint256", 86 | "name": "", 87 | "type": "uint256" 88 | } 89 | ], 90 | "stateMutability": "view", 91 | "type": "function" 92 | } 93 | ] 94 | -------------------------------------------------------------------------------- /abi/IDelegatorBeacon.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "owner", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "nonpayable", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/IDelegatorFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_operator", 7 | "type": "address" 8 | } 9 | ], 10 | "name": "createDelegator", 11 | "outputs": [ 12 | { 13 | "internalType": "address", 14 | "name": "", 15 | "type": "address" 16 | } 17 | ], 18 | "stateMutability": "nonpayable", 19 | "type": "function" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "vault", 24 | "outputs": [ 25 | { 26 | "internalType": "address", 27 | "name": "", 28 | "type": "address" 29 | } 30 | ], 31 | "stateMutability": "nonpayable", 32 | "type": "function" 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /abi/IEIP712.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "DOMAIN_SEPARATOR", 5 | "outputs": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "", 9 | "type": "bytes32" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/IERC165Upgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "bytes4", 6 | "name": "interfaceId", 7 | "type": "bytes4" 8 | } 9 | ], 10 | "name": "supportsInterface", 11 | "outputs": [ 12 | { 13 | "internalType": "bool", 14 | "name": "", 15 | "type": "bool" 16 | } 17 | ], 18 | "stateMutability": "view", 19 | "type": "function" 20 | } 21 | ] 22 | -------------------------------------------------------------------------------- /abi/IERC1822Proxiable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "proxiableUUID", 5 | "outputs": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "", 9 | "type": "bytes32" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/IERC1822ProxiableUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "proxiableUUID", 5 | "outputs": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "", 9 | "type": "bytes32" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/IERC20Permit.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "DOMAIN_SEPARATOR", 5 | "outputs": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "", 9 | "type": "bytes32" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [ 17 | { 18 | "internalType": "address", 19 | "name": "owner", 20 | "type": "address" 21 | } 22 | ], 23 | "name": "nonces", 24 | "outputs": [ 25 | { 26 | "internalType": "uint256", 27 | "name": "", 28 | "type": "uint256" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [ 36 | { 37 | "internalType": "address", 38 | "name": "owner", 39 | "type": "address" 40 | }, 41 | { 42 | "internalType": "address", 43 | "name": "spender", 44 | "type": "address" 45 | }, 46 | { 47 | "internalType": "uint256", 48 | "name": "value", 49 | "type": "uint256" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "deadline", 54 | "type": "uint256" 55 | }, 56 | { 57 | "internalType": "uint8", 58 | "name": "v", 59 | "type": "uint8" 60 | }, 61 | { 62 | "internalType": "bytes32", 63 | "name": "r", 64 | "type": "bytes32" 65 | }, 66 | { 67 | "internalType": "bytes32", 68 | "name": "s", 69 | "type": "bytes32" 70 | } 71 | ], 72 | "name": "permit", 73 | "outputs": [], 74 | "stateMutability": "nonpayable", 75 | "type": "function" 76 | } 77 | ] 78 | -------------------------------------------------------------------------------- /abi/IERC20PermitUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "DOMAIN_SEPARATOR", 5 | "outputs": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "", 9 | "type": "bytes32" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [ 17 | { 18 | "internalType": "address", 19 | "name": "owner", 20 | "type": "address" 21 | } 22 | ], 23 | "name": "nonces", 24 | "outputs": [ 25 | { 26 | "internalType": "uint256", 27 | "name": "", 28 | "type": "uint256" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [ 36 | { 37 | "internalType": "address", 38 | "name": "owner", 39 | "type": "address" 40 | }, 41 | { 42 | "internalType": "address", 43 | "name": "spender", 44 | "type": "address" 45 | }, 46 | { 47 | "internalType": "uint256", 48 | "name": "value", 49 | "type": "uint256" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "deadline", 54 | "type": "uint256" 55 | }, 56 | { 57 | "internalType": "uint8", 58 | "name": "v", 59 | "type": "uint8" 60 | }, 61 | { 62 | "internalType": "bytes32", 63 | "name": "r", 64 | "type": "bytes32" 65 | }, 66 | { 67 | "internalType": "bytes32", 68 | "name": "s", 69 | "type": "bytes32" 70 | } 71 | ], 72 | "name": "permit", 73 | "outputs": [], 74 | "stateMutability": "nonpayable", 75 | "type": "function" 76 | } 77 | ] 78 | -------------------------------------------------------------------------------- /abi/IERC721Receiver.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "operator", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "from", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "uint256", 16 | "name": "tokenId", 17 | "type": "uint256" 18 | }, 19 | { 20 | "internalType": "bytes", 21 | "name": "data", 22 | "type": "bytes" 23 | } 24 | ], 25 | "name": "onERC721Received", 26 | "outputs": [ 27 | { 28 | "internalType": "bytes4", 29 | "name": "", 30 | "type": "bytes4" 31 | } 32 | ], 33 | "stateMutability": "nonpayable", 34 | "type": "function" 35 | } 36 | ] 37 | -------------------------------------------------------------------------------- /abi/IFlashLoanReceiver.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "ADDRESSES_PROVIDER", 5 | "outputs": [ 6 | { 7 | "internalType": "contract IPoolAddressesProvider", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "POOL", 18 | "outputs": [ 19 | { 20 | "internalType": "contract IPool", 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [ 30 | { 31 | "internalType": "address[]", 32 | "name": "assets", 33 | "type": "address[]" 34 | }, 35 | { 36 | "internalType": "uint256[]", 37 | "name": "amounts", 38 | "type": "uint256[]" 39 | }, 40 | { 41 | "internalType": "uint256[]", 42 | "name": "premiums", 43 | "type": "uint256[]" 44 | }, 45 | { 46 | "internalType": "address", 47 | "name": "initiator", 48 | "type": "address" 49 | }, 50 | { 51 | "internalType": "bytes", 52 | "name": "params", 53 | "type": "bytes" 54 | } 55 | ], 56 | "name": "executeOperation", 57 | "outputs": [ 58 | { 59 | "internalType": "bool", 60 | "name": "", 61 | "type": "bool" 62 | } 63 | ], 64 | "stateMutability": "nonpayable", 65 | "type": "function" 66 | } 67 | ] 68 | -------------------------------------------------------------------------------- /abi/IFlashLoanRecipient.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "contract ERC20[]", 6 | "name": "tokens", 7 | "type": "address[]" 8 | }, 9 | { 10 | "internalType": "uint256[]", 11 | "name": "amounts", 12 | "type": "uint256[]" 13 | }, 14 | { 15 | "internalType": "uint256[]", 16 | "name": "feeAmounts", 17 | "type": "uint256[]" 18 | }, 19 | { 20 | "internalType": "bytes", 21 | "name": "userData", 22 | "type": "bytes" 23 | } 24 | ], 25 | "name": "receiveFlashLoan", 26 | "outputs": [], 27 | "stateMutability": "nonpayable", 28 | "type": "function" 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /abi/IMakerAdapter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "usr", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "uint256", 11 | "name": "val", 12 | "type": "uint256" 13 | } 14 | ], 15 | "name": "exit", 16 | "outputs": [], 17 | "stateMutability": "nonpayable", 18 | "type": "function" 19 | }, 20 | { 21 | "inputs": [ 22 | { 23 | "internalType": "address", 24 | "name": "urn", 25 | "type": "address" 26 | }, 27 | { 28 | "internalType": "address", 29 | "name": "usr", 30 | "type": "address" 31 | }, 32 | { 33 | "internalType": "uint256", 34 | "name": "val", 35 | "type": "uint256" 36 | } 37 | ], 38 | "name": "join", 39 | "outputs": [], 40 | "stateMutability": "nonpayable", 41 | "type": "function" 42 | } 43 | ] 44 | -------------------------------------------------------------------------------- /abi/IMinter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "gauge", 7 | "type": "address" 8 | } 9 | ], 10 | "name": "mint", 11 | "outputs": [], 12 | "stateMutability": "nonpayable", 13 | "type": "function" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/IPeripheryImmutableState.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "WETH9", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "factory", 18 | "outputs": [ 19 | { 20 | "internalType": "address", 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /abi/IPeripheryPayments.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "refundETH", 5 | "outputs": [], 6 | "stateMutability": "payable", 7 | "type": "function" 8 | }, 9 | { 10 | "inputs": [ 11 | { 12 | "internalType": "address", 13 | "name": "token", 14 | "type": "address" 15 | }, 16 | { 17 | "internalType": "uint256", 18 | "name": "amountMinimum", 19 | "type": "uint256" 20 | }, 21 | { 22 | "internalType": "address", 23 | "name": "recipient", 24 | "type": "address" 25 | } 26 | ], 27 | "name": "sweepToken", 28 | "outputs": [], 29 | "stateMutability": "payable", 30 | "type": "function" 31 | }, 32 | { 33 | "inputs": [ 34 | { 35 | "internalType": "uint256", 36 | "name": "amountMinimum", 37 | "type": "uint256" 38 | }, 39 | { 40 | "internalType": "address", 41 | "name": "recipient", 42 | "type": "address" 43 | } 44 | ], 45 | "name": "unwrapWETH9", 46 | "outputs": [], 47 | "stateMutability": "payable", 48 | "type": "function" 49 | } 50 | ] 51 | -------------------------------------------------------------------------------- /abi/IPoolInitializer.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "token0", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "token1", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "uint24", 16 | "name": "fee", 17 | "type": "uint24" 18 | }, 19 | { 20 | "internalType": "uint160", 21 | "name": "sqrtPriceX96", 22 | "type": "uint160" 23 | } 24 | ], 25 | "name": "createAndInitializePoolIfNecessary", 26 | "outputs": [ 27 | { 28 | "internalType": "address", 29 | "name": "pool", 30 | "type": "address" 31 | } 32 | ], 33 | "stateMutability": "payable", 34 | "type": "function" 35 | } 36 | ] 37 | -------------------------------------------------------------------------------- /abi/IRewards.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "comet", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "src", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "bool", 16 | "name": "shouldAccrue", 17 | "type": "bool" 18 | } 19 | ], 20 | "name": "claim", 21 | "outputs": [], 22 | "stateMutability": "nonpayable", 23 | "type": "function" 24 | }, 25 | { 26 | "inputs": [ 27 | { 28 | "internalType": "address", 29 | "name": "comet", 30 | "type": "address" 31 | }, 32 | { 33 | "internalType": "address", 34 | "name": "account", 35 | "type": "address" 36 | } 37 | ], 38 | "name": "getRewardOwed", 39 | "outputs": [ 40 | { 41 | "components": [ 42 | { 43 | "internalType": "address", 44 | "name": "token", 45 | "type": "address" 46 | }, 47 | { 48 | "internalType": "uint256", 49 | "name": "owed", 50 | "type": "uint256" 51 | } 52 | ], 53 | "internalType": "struct CometStructs.RewardOwed", 54 | "name": "", 55 | "type": "tuple" 56 | } 57 | ], 58 | "stateMutability": "nonpayable", 59 | "type": "function" 60 | } 61 | ] 62 | -------------------------------------------------------------------------------- /abi/IRootChainManager.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "user", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "rootToken", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "bytes", 16 | "name": "depositData", 17 | "type": "bytes" 18 | } 19 | ], 20 | "name": "depositFor", 21 | "outputs": [], 22 | "stateMutability": "nonpayable", 23 | "type": "function" 24 | }, 25 | { 26 | "inputs": [ 27 | { 28 | "internalType": "bytes", 29 | "name": "_data", 30 | "type": "bytes" 31 | } 32 | ], 33 | "name": "exit", 34 | "outputs": [], 35 | "stateMutability": "nonpayable", 36 | "type": "function" 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /abi/IScaledBalanceToken.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "user", 7 | "type": "address" 8 | } 9 | ], 10 | "name": "getScaledUserBalanceAndSupply", 11 | "outputs": [ 12 | { 13 | "internalType": "uint256", 14 | "name": "", 15 | "type": "uint256" 16 | }, 17 | { 18 | "internalType": "uint256", 19 | "name": "", 20 | "type": "uint256" 21 | } 22 | ], 23 | "stateMutability": "view", 24 | "type": "function" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "address", 30 | "name": "user", 31 | "type": "address" 32 | } 33 | ], 34 | "name": "scaledBalanceOf", 35 | "outputs": [ 36 | { 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "stateMutability": "view", 43 | "type": "function" 44 | }, 45 | { 46 | "inputs": [], 47 | "name": "scaledTotalSupply", 48 | "outputs": [ 49 | { 50 | "internalType": "uint256", 51 | "name": "", 52 | "type": "uint256" 53 | } 54 | ], 55 | "stateMutability": "view", 56 | "type": "function" 57 | } 58 | ] 59 | -------------------------------------------------------------------------------- /abi/IStrategy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "", 7 | "type": "address" 8 | } 9 | ], 10 | "name": "shares", 11 | "outputs": [ 12 | { 13 | "internalType": "uint256", 14 | "name": "", 15 | "type": "uint256" 16 | } 17 | ], 18 | "stateMutability": "view", 19 | "type": "function" 20 | }, 21 | { 22 | "inputs": [ 23 | { 24 | "internalType": "uint256", 25 | "name": "", 26 | "type": "uint256" 27 | } 28 | ], 29 | "name": "sharesToUnderlying", 30 | "outputs": [ 31 | { 32 | "internalType": "uint256", 33 | "name": "", 34 | "type": "uint256" 35 | } 36 | ], 37 | "stateMutability": "view", 38 | "type": "function" 39 | }, 40 | { 41 | "inputs": [ 42 | { 43 | "internalType": "uint256", 44 | "name": "", 45 | "type": "uint256" 46 | } 47 | ], 48 | "name": "sharesToUnderlyingView", 49 | "outputs": [ 50 | { 51 | "internalType": "uint256", 52 | "name": "", 53 | "type": "uint256" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [ 61 | { 62 | "internalType": "uint256", 63 | "name": "", 64 | "type": "uint256" 65 | } 66 | ], 67 | "name": "underlyingToShares", 68 | "outputs": [ 69 | { 70 | "internalType": "uint256", 71 | "name": "", 72 | "type": "uint256" 73 | } 74 | ], 75 | "stateMutability": "view", 76 | "type": "function" 77 | }, 78 | { 79 | "inputs": [ 80 | { 81 | "internalType": "address", 82 | "name": "", 83 | "type": "address" 84 | } 85 | ], 86 | "name": "userUnderlyingView", 87 | "outputs": [ 88 | { 89 | "internalType": "uint256", 90 | "name": "", 91 | "type": "uint256" 92 | } 93 | ], 94 | "stateMutability": "view", 95 | "type": "function" 96 | } 97 | ] 98 | -------------------------------------------------------------------------------- /abi/IStrategyManager.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "uint256", 16 | "name": "", 17 | "type": "uint256" 18 | } 19 | ], 20 | "name": "depositIntoStrategy", 21 | "outputs": [], 22 | "stateMutability": "nonpayable", 23 | "type": "function" 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /abi/IUltraLRT.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "HARVESTER", 5 | "outputs": [ 6 | { 7 | "internalType": "bytes32", 8 | "name": "", 9 | "type": "bytes32" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [ 17 | { 18 | "internalType": "bytes32", 19 | "name": "role", 20 | "type": "bytes32" 21 | }, 22 | { 23 | "internalType": "address", 24 | "name": "user", 25 | "type": "address" 26 | } 27 | ], 28 | "name": "hasRole", 29 | "outputs": [ 30 | { 31 | "internalType": "bool", 32 | "name": "", 33 | "type": "bool" 34 | } 35 | ], 36 | "stateMutability": "view", 37 | "type": "function" 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /abi/IUniswapV3PoolDerivedState.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "uint32[]", 6 | "name": "secondsAgos", 7 | "type": "uint32[]" 8 | } 9 | ], 10 | "name": "observe", 11 | "outputs": [ 12 | { 13 | "internalType": "int56[]", 14 | "name": "tickCumulatives", 15 | "type": "int56[]" 16 | }, 17 | { 18 | "internalType": "uint160[]", 19 | "name": "secondsPerLiquidityCumulativeX128s", 20 | "type": "uint160[]" 21 | } 22 | ], 23 | "stateMutability": "view", 24 | "type": "function" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "int24", 30 | "name": "tickLower", 31 | "type": "int24" 32 | }, 33 | { 34 | "internalType": "int24", 35 | "name": "tickUpper", 36 | "type": "int24" 37 | } 38 | ], 39 | "name": "snapshotCumulativesInside", 40 | "outputs": [ 41 | { 42 | "internalType": "int56", 43 | "name": "tickCumulativeInside", 44 | "type": "int56" 45 | }, 46 | { 47 | "internalType": "uint160", 48 | "name": "secondsPerLiquidityInsideX128", 49 | "type": "uint160" 50 | }, 51 | { 52 | "internalType": "uint32", 53 | "name": "secondsInside", 54 | "type": "uint32" 55 | } 56 | ], 57 | "stateMutability": "view", 58 | "type": "function" 59 | } 60 | ] 61 | -------------------------------------------------------------------------------- /abi/IUniswapV3PoolErrors.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "AI", 5 | "type": "error" 6 | }, 7 | { 8 | "inputs": [], 9 | "name": "AS", 10 | "type": "error" 11 | }, 12 | { 13 | "inputs": [], 14 | "name": "F0", 15 | "type": "error" 16 | }, 17 | { 18 | "inputs": [], 19 | "name": "F1", 20 | "type": "error" 21 | }, 22 | { 23 | "inputs": [], 24 | "name": "IIA", 25 | "type": "error" 26 | }, 27 | { 28 | "inputs": [], 29 | "name": "L", 30 | "type": "error" 31 | }, 32 | { 33 | "inputs": [], 34 | "name": "LOK", 35 | "type": "error" 36 | }, 37 | { 38 | "inputs": [], 39 | "name": "M0", 40 | "type": "error" 41 | }, 42 | { 43 | "inputs": [], 44 | "name": "M1", 45 | "type": "error" 46 | }, 47 | { 48 | "inputs": [], 49 | "name": "TLM", 50 | "type": "error" 51 | }, 52 | { 53 | "inputs": [], 54 | "name": "TLU", 55 | "type": "error" 56 | }, 57 | { 58 | "inputs": [], 59 | "name": "TUM", 60 | "type": "error" 61 | } 62 | ] 63 | -------------------------------------------------------------------------------- /abi/IUniswapV3PoolImmutables.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "factory", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "fee", 18 | "outputs": [ 19 | { 20 | "internalType": "uint24", 21 | "name": "", 22 | "type": "uint24" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [], 30 | "name": "maxLiquidityPerTick", 31 | "outputs": [ 32 | { 33 | "internalType": "uint128", 34 | "name": "", 35 | "type": "uint128" 36 | } 37 | ], 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "tickSpacing", 44 | "outputs": [ 45 | { 46 | "internalType": "int24", 47 | "name": "", 48 | "type": "int24" 49 | } 50 | ], 51 | "stateMutability": "view", 52 | "type": "function" 53 | }, 54 | { 55 | "inputs": [], 56 | "name": "token0", 57 | "outputs": [ 58 | { 59 | "internalType": "address", 60 | "name": "", 61 | "type": "address" 62 | } 63 | ], 64 | "stateMutability": "view", 65 | "type": "function" 66 | }, 67 | { 68 | "inputs": [], 69 | "name": "token1", 70 | "outputs": [ 71 | { 72 | "internalType": "address", 73 | "name": "", 74 | "type": "address" 75 | } 76 | ], 77 | "stateMutability": "view", 78 | "type": "function" 79 | } 80 | ] 81 | -------------------------------------------------------------------------------- /abi/IUniswapV3PoolOwnerActions.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "recipient", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "uint128", 11 | "name": "amount0Requested", 12 | "type": "uint128" 13 | }, 14 | { 15 | "internalType": "uint128", 16 | "name": "amount1Requested", 17 | "type": "uint128" 18 | } 19 | ], 20 | "name": "collectProtocol", 21 | "outputs": [ 22 | { 23 | "internalType": "uint128", 24 | "name": "amount0", 25 | "type": "uint128" 26 | }, 27 | { 28 | "internalType": "uint128", 29 | "name": "amount1", 30 | "type": "uint128" 31 | } 32 | ], 33 | "stateMutability": "nonpayable", 34 | "type": "function" 35 | }, 36 | { 37 | "inputs": [ 38 | { 39 | "internalType": "uint8", 40 | "name": "feeProtocol0", 41 | "type": "uint8" 42 | }, 43 | { 44 | "internalType": "uint8", 45 | "name": "feeProtocol1", 46 | "type": "uint8" 47 | } 48 | ], 49 | "name": "setFeeProtocol", 50 | "outputs": [], 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | } 54 | ] 55 | -------------------------------------------------------------------------------- /abi/IUniswapV3SwapCallback.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "int256", 6 | "name": "amount0Delta", 7 | "type": "int256" 8 | }, 9 | { 10 | "internalType": "int256", 11 | "name": "amount1Delta", 12 | "type": "int256" 13 | }, 14 | { 15 | "internalType": "bytes", 16 | "name": "data", 17 | "type": "bytes" 18 | } 19 | ], 20 | "name": "uniswapV3SwapCallback", 21 | "outputs": [], 22 | "stateMutability": "nonpayable", 23 | "type": "function" 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /abi/Initializable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint8", 8 | "name": "version", 9 | "type": "uint8" 10 | } 11 | ], 12 | "name": "Initialized", 13 | "type": "event" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/Multicallable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "bytes[]", 6 | "name": "data", 7 | "type": "bytes[]" 8 | } 9 | ], 10 | "name": "multicall", 11 | "outputs": [ 12 | { 13 | "internalType": "bytes[]", 14 | "name": "results", 15 | "type": "bytes[]" 16 | } 17 | ], 18 | "stateMutability": "payable", 19 | "type": "function" 20 | } 21 | ] 22 | -------------------------------------------------------------------------------- /abi/NftGate.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "accessNft", 5 | "outputs": [ 6 | { 7 | "internalType": "contract ERC721", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "governance", 18 | "outputs": [ 19 | { 20 | "internalType": "address", 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [ 30 | { 31 | "internalType": "contract ERC721", 32 | "name": "_accessNft", 33 | "type": "address" 34 | } 35 | ], 36 | "name": "setAccessNft", 37 | "outputs": [], 38 | "stateMutability": "nonpayable", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [ 43 | { 44 | "internalType": "bool", 45 | "name": "_needNftToDeposit", 46 | "type": "bool" 47 | }, 48 | { 49 | "internalType": "bool", 50 | "name": "_nftDiscountActive", 51 | "type": "bool" 52 | } 53 | ], 54 | "name": "setNftProperties", 55 | "outputs": [], 56 | "stateMutability": "nonpayable", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [ 61 | { 62 | "internalType": "uint16", 63 | "name": "_newFee", 64 | "type": "uint16" 65 | } 66 | ], 67 | "name": "setWithdrawalFeeWithNft", 68 | "outputs": [], 69 | "stateMutability": "nonpayable", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "withdrawalFeeWithNft", 75 | "outputs": [ 76 | { 77 | "internalType": "uint16", 78 | "name": "", 79 | "type": "uint16" 80 | } 81 | ], 82 | "stateMutability": "view", 83 | "type": "function" 84 | } 85 | ] 86 | -------------------------------------------------------------------------------- /abi/Ownable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "previousOwner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "newOwner", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "OwnershipTransferred", 19 | "type": "event" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "owner", 24 | "outputs": [ 25 | { 26 | "internalType": "address", 27 | "name": "", 28 | "type": "address" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [], 36 | "name": "renounceOwnership", 37 | "outputs": [], 38 | "stateMutability": "nonpayable", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [ 43 | { 44 | "internalType": "address", 45 | "name": "newOwner", 46 | "type": "address" 47 | } 48 | ], 49 | "name": "transferOwnership", 50 | "outputs": [], 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | } 54 | ] 55 | -------------------------------------------------------------------------------- /abi/OwnableUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint8", 8 | "name": "version", 9 | "type": "uint8" 10 | } 11 | ], 12 | "name": "Initialized", 13 | "type": "event" 14 | }, 15 | { 16 | "anonymous": false, 17 | "inputs": [ 18 | { 19 | "indexed": true, 20 | "internalType": "address", 21 | "name": "previousOwner", 22 | "type": "address" 23 | }, 24 | { 25 | "indexed": true, 26 | "internalType": "address", 27 | "name": "newOwner", 28 | "type": "address" 29 | } 30 | ], 31 | "name": "OwnershipTransferred", 32 | "type": "event" 33 | }, 34 | { 35 | "inputs": [], 36 | "name": "owner", 37 | "outputs": [ 38 | { 39 | "internalType": "address", 40 | "name": "", 41 | "type": "address" 42 | } 43 | ], 44 | "stateMutability": "view", 45 | "type": "function" 46 | }, 47 | { 48 | "inputs": [], 49 | "name": "renounceOwnership", 50 | "outputs": [], 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | }, 54 | { 55 | "inputs": [ 56 | { 57 | "internalType": "address", 58 | "name": "newOwner", 59 | "type": "address" 60 | } 61 | ], 62 | "name": "transferOwnership", 63 | "outputs": [], 64 | "stateMutability": "nonpayable", 65 | "type": "function" 66 | } 67 | ] 68 | -------------------------------------------------------------------------------- /abi/PausableUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint8", 8 | "name": "version", 9 | "type": "uint8" 10 | } 11 | ], 12 | "name": "Initialized", 13 | "type": "event" 14 | }, 15 | { 16 | "anonymous": false, 17 | "inputs": [ 18 | { 19 | "indexed": false, 20 | "internalType": "address", 21 | "name": "account", 22 | "type": "address" 23 | } 24 | ], 25 | "name": "Paused", 26 | "type": "event" 27 | }, 28 | { 29 | "anonymous": false, 30 | "inputs": [ 31 | { 32 | "indexed": false, 33 | "internalType": "address", 34 | "name": "account", 35 | "type": "address" 36 | } 37 | ], 38 | "name": "Unpaused", 39 | "type": "event" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "paused", 44 | "outputs": [ 45 | { 46 | "internalType": "bool", 47 | "name": "", 48 | "type": "bool" 49 | } 50 | ], 51 | "stateMutability": "view", 52 | "type": "function" 53 | } 54 | ] 55 | -------------------------------------------------------------------------------- /abi/Proxy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "stateMutability": "payable", 4 | "type": "fallback" 5 | }, 6 | { 7 | "stateMutability": "payable", 8 | "type": "receive" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /abi/RebalanceModule.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "contract AffineVault", 8 | "name": "vault", 9 | "type": "address" 10 | } 11 | ], 12 | "name": "Rebalance", 13 | "type": "event" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "rebalance", 18 | "outputs": [], 19 | "stateMutability": "nonpayable", 20 | "type": "function" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /abi/RebalanceStorage.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "governance", 5 | "outputs": [ 6 | { 7 | "internalType": "address", 8 | "name": "", 9 | "type": "address" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "rebalanceModule", 18 | "outputs": [ 19 | { 20 | "internalType": "contract RebalanceModule", 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [ 30 | { 31 | "internalType": "address", 32 | "name": "_rebalanceModule", 33 | "type": "address" 34 | } 35 | ], 36 | "name": "setRebalanceModule", 37 | "outputs": [], 38 | "stateMutability": "nonpayable", 39 | "type": "function" 40 | } 41 | ] 42 | -------------------------------------------------------------------------------- /abi/ReentrancyGuard.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "ReentrancyGuardReentrantCall", 5 | "type": "error" 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /abi/ReentrancyGuardUpgradeable.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "uint8", 8 | "name": "version", 9 | "type": "uint8" 10 | } 11 | ], 12 | "name": "Initialized", 13 | "type": "event" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /abi/SymDelegatorFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_vault", 7 | "type": "address" 8 | } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [ 15 | { 16 | "internalType": "address", 17 | "name": "_collateral", 18 | "type": "address" 19 | } 20 | ], 21 | "name": "createDelegator", 22 | "outputs": [ 23 | { 24 | "internalType": "address", 25 | "name": "proxy", 26 | "type": "address" 27 | } 28 | ], 29 | "stateMutability": "nonpayable", 30 | "type": "function" 31 | }, 32 | { 33 | "inputs": [], 34 | "name": "vault", 35 | "outputs": [ 36 | { 37 | "internalType": "address", 38 | "name": "", 39 | "type": "address" 40 | } 41 | ], 42 | "stateMutability": "view", 43 | "type": "function" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /abi/VaultErrors.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "OnlyEscrow", 5 | "type": "error" 6 | }, 7 | { 8 | "inputs": [], 9 | "name": "OnlyWormholeRouter", 10 | "type": "error" 11 | }, 12 | { 13 | "inputs": [], 14 | "name": "ProfitUnlocking", 15 | "type": "error" 16 | }, 17 | { 18 | "inputs": [], 19 | "name": "SharesExceedBalance", 20 | "type": "error" 21 | }, 22 | { 23 | "inputs": [], 24 | "name": "TooManyStrategyBps", 25 | "type": "error" 26 | }, 27 | { 28 | "inputs": [], 29 | "name": "TvlLimitReached", 30 | "type": "error" 31 | }, 32 | { 33 | "inputs": [], 34 | "name": "ZeroShares", 35 | "type": "error" 36 | } 37 | ] 38 | -------------------------------------------------------------------------------- /abi/WormholeRouter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "consistencyLevel", 5 | "outputs": [ 6 | { 7 | "internalType": "uint8", 8 | "name": "", 9 | "type": "uint8" 10 | } 11 | ], 12 | "stateMutability": "view", 13 | "type": "function" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "governance", 18 | "outputs": [ 19 | { 20 | "internalType": "address", 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "inputs": [], 30 | "name": "nextValidNonce", 31 | "outputs": [ 32 | { 33 | "internalType": "uint256", 34 | "name": "", 35 | "type": "uint256" 36 | } 37 | ], 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "otherLayerWormholeId", 44 | "outputs": [ 45 | { 46 | "internalType": "uint16", 47 | "name": "", 48 | "type": "uint16" 49 | } 50 | ], 51 | "stateMutability": "view", 52 | "type": "function" 53 | }, 54 | { 55 | "inputs": [ 56 | { 57 | "internalType": "uint8", 58 | "name": "_consistencyLevel", 59 | "type": "uint8" 60 | } 61 | ], 62 | "name": "setConsistencyLevel", 63 | "outputs": [], 64 | "stateMutability": "nonpayable", 65 | "type": "function" 66 | }, 67 | { 68 | "inputs": [], 69 | "name": "vault", 70 | "outputs": [ 71 | { 72 | "internalType": "contract BaseVault", 73 | "name": "", 74 | "type": "address" 75 | } 76 | ], 77 | "stateMutability": "view", 78 | "type": "function" 79 | }, 80 | { 81 | "inputs": [], 82 | "name": "wormhole", 83 | "outputs": [ 84 | { 85 | "internalType": "contract IWormhole", 86 | "name": "", 87 | "type": "address" 88 | } 89 | ], 90 | "stateMutability": "view", 91 | "type": "function" 92 | } 93 | ] 94 | -------------------------------------------------------------------------------- /audits/Affine_DeFi_Multiplyr_Smart_Contract_Security_Audit_Report_Halborn_Final_oct_22.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/audits/Affine_DeFi_Multiplyr_Smart_Contract_Security_Audit_Report_Halborn_Final_oct_22.pdf -------------------------------------------------------------------------------- /audits/Affine_ultraETH_LRT_Audit_May24_MaslarovK_Final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/audits/Affine_ultraETH_LRT_Audit_May24_MaslarovK_Final.pdf -------------------------------------------------------------------------------- /audits/Affine_ultraETH_LRT_Audit_Quantstamp_June24_Final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/audits/Affine_ultraETH_LRT_Audit_Quantstamp_June24_Final.pdf -------------------------------------------------------------------------------- /docs/coverage/amber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/docs/coverage/amber.png -------------------------------------------------------------------------------- /docs/coverage/emerald.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/docs/coverage/emerald.png -------------------------------------------------------------------------------- /docs/coverage/glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/docs/coverage/glass.png -------------------------------------------------------------------------------- /docs/coverage/ruby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/docs/coverage/ruby.png -------------------------------------------------------------------------------- /docs/coverage/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/docs/coverage/snow.png -------------------------------------------------------------------------------- /docs/coverage/updown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/docs/coverage/updown.png -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | out = "out" 3 | libs = ['lib', 'node_modules'] 4 | block_timestamp = 1 5 | verbosity = 3 6 | solc_version = "0.8.16" 7 | optimizer_runs = 0 8 | fs_permissions = [{ access = "read-write", path = "./"}] 9 | 10 | [profile.default.fuzz] 11 | seed="0x64" 12 | 13 | [profile.default.fmt] 14 | number_underscore = "thousands" 15 | 16 | [profile.default.rpc_endpoints] 17 | ethereum = "https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ETH_MAINNET_KEY}" 18 | goerli = "https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_ETH_GOERLI_KEY}" 19 | sepolia = "https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_ETH_SEPOLIA_KEY}" 20 | 21 | polygon = "https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_POLYGON_MAINNET_KEY}" 22 | mumbai = "https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_POLYGON_MUMBAI_KEY}" 23 | 24 | arbitrum = "https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_ARB_MAINNET_KEY}" 25 | base = "https://base-mainnet.g.alchemy.com/v2/${ALCHEMY_BASE_MAINNET_KEY}" 26 | base-goerli = "https://base-goerli.g.alchemy.com/v2/${ALCHEMY_BASE_TESTNET_KEY}" 27 | holesky = "https://ethereum-holesky-rpc.publicnode.com" 28 | 29 | [etherscan] 30 | ethereum = { key = "${ETHERSCAN_MAINNET_KEY}", chain = 1 } 31 | goerli = { key = "${ETHERSCAN_MAINNET_KEY}", chain = 5, url = "https://api-goerli.etherscan.io/api?"} 32 | holesky = {key = "${ETHERSCAN_MAINNET_KEY}", chain = 17000, url = "https://api-holesky.etherscan.io/api?"} 33 | sepolia = { key = "${ETHERSCAN_MAINNET_KEY}", chain = 11155111, url = "https://api-sepolia.etherscan.io/api?"} 34 | 35 | polygon = { key = "${POLYGONSCAN_API_KEY}", chain = 137, url = "https://api.polygonscan.com/api?" } 36 | mumbai = { key = "${POLYGONSCAN_API_KEY}", chain = 80001, url = "https://api-testnet.polygonscan.com/api?" } 37 | 38 | 39 | base = { key = "${BASESCAN_API_KEY}", chain = "base" , url = "https://api.basescan.org/api?"} 40 | base-goerli = { key = "${BASESCAN_API_KEY}", chain = 84531, url = "https://api-goerli.basescan.org/api?"} 41 | 42 | 43 | [profile.ci.fuzz] 44 | runs = 10000 -------------------------------------------------------------------------------- /gencov.sh: -------------------------------------------------------------------------------- 1 | forge coverage --report lcov 2 | genhtml lcov.info --branch-coverage --output-dir docs/coverage --ignore-errors inconsistent 3 | -------------------------------------------------------------------------------- /remappings.txt: -------------------------------------------------------------------------------- 1 | forge-std/=lib/forge-std/src/ 2 | src/=src/ 3 | script/=script/ -------------------------------------------------------------------------------- /script/AAVEV3Strategy.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script, console2} from "forge-std/Script.sol"; 5 | 6 | import {AffineVault} from "src/vaults/AffineVault.sol"; 7 | import {AaveV3Strategy, IPool} from "src/strategies/AaveV3Strategy.sol"; 8 | 9 | /* solhint-disable reason-string, no-console */ 10 | 11 | contract Deploy is Script { 12 | function run() external { 13 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 14 | vm.startBroadcast(deployer); 15 | 16 | AffineVault vault = AffineVault(0x3A6B57ea121fbAB06f5A7Bf0626702EcB0Db7f11); 17 | AaveV3Strategy strategy = new AaveV3Strategy(vault, IPool(0xA238Dd80C259a72e81d7e4664a9801593F98d1c5)); 18 | require(strategy.vault() == vault); 19 | } 20 | 21 | function runPoly() external { 22 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 23 | vm.startBroadcast(deployer); 24 | 25 | console2.log("dep %s", deployer); 26 | 27 | AffineVault vault = AffineVault(0x829363736a5A9080e05549Db6d1271f070a7e224); 28 | AaveV3Strategy strategy = new AaveV3Strategy(vault, IPool(0x794a61358D6845594F94dc1DB02A252b5b4814aD)); 29 | 30 | console2.log("strat %s", address(strategy)); 31 | require(strategy.vault() == vault); 32 | require(address(strategy.asset()) == address(vault.asset())); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /script/AaveV2Strategy.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script, console2} from "forge-std/Script.sol"; 5 | 6 | import {AffineVault} from "src/vaults/AffineVault.sol"; 7 | import {AaveV2Strategy, ILendingPool} from "src/strategies/audited/AaveV2Strategy.sol"; 8 | 9 | /* solhint-disable reason-string, no-console */ 10 | 11 | contract Deploy is Script { 12 | function run() external { 13 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 14 | vm.startBroadcast(deployer); 15 | 16 | AffineVault vault = AffineVault(0x84eF1F1A7f14A237c4b1DA8d13548123879FC3A9); 17 | AaveV2Strategy strategy = new AaveV2Strategy(vault, ILendingPool(0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9)); 18 | require(strategy.vault() == vault); 19 | } 20 | 21 | function runEthEarn() external { 22 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 23 | vm.startBroadcast(deployer); 24 | 25 | AffineVault vault = AffineVault(0x72D51B2233c5feA8a702FDd0E51B0adE95638f2c); 26 | AaveV2Strategy strategy = new AaveV2Strategy(vault, ILendingPool(0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9)); 27 | require(strategy.vault() == vault); 28 | console2.log("asset: ", address(strategy.asset())); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /script/Base.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script, console2} from "forge-std/Script.sol"; 5 | import {stdJson} from "forge-std/StdJson.sol"; 6 | 7 | abstract contract Base is Script { 8 | using stdJson for string; 9 | 10 | struct L1Config { 11 | address chainManager; 12 | address erc20Predicate; 13 | address governance; 14 | address usdc; 15 | address weth; 16 | address wormhole; 17 | } 18 | 19 | // The chainlink asset / usd (dollars per asset) feeds 20 | struct Feeds { 21 | address usdc; 22 | address wbtc; 23 | address weth; 24 | } 25 | 26 | struct L2Config { 27 | address governance; 28 | address usdc; 29 | address wormhole; 30 | uint256 withdrawFee; 31 | uint256 managementFee; 32 | uint256 ewqMinAssets; 33 | uint256 ewqMinFee; 34 | address wbtc; 35 | address weth; 36 | address wmatic; 37 | Feeds feeds; 38 | address aaveRegistry; 39 | } 40 | 41 | function _getConfigJson(bool mainnet, bool layer1) internal view returns (bytes memory) { 42 | string memory root = vm.projectRoot(); 43 | string memory path = string.concat(root, "/script/config.json"); 44 | string memory allJson = vm.readFile(path); 45 | string memory key = string.concat(".", mainnet ? "mainnet" : "testnet", ".", layer1 ? "l1" : "l2"); 46 | return allJson.parseRaw(key); 47 | } 48 | 49 | function _getSalt() internal returns (bytes32 salt) { 50 | string[] memory inputs = new string[](4); 51 | inputs[0] = "yarn"; 52 | inputs[1] = "--silent"; 53 | inputs[2] = "ts-node"; 54 | inputs[3] = "scripts/utils/get-bytes.ts"; 55 | bytes memory res = vm.ffi(inputs); 56 | salt = keccak256(res); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /script/CompoundV3Strategy.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | import {Script, console2} from "forge-std/Script.sol"; 7 | 8 | import {AffineVault} from "src/vaults/AffineVault.sol"; 9 | import {CompoundV3Strategy, IComet, IRewards, IUniswapV2Router02} from "src/strategies/CompoundV3Strategy.sol"; 10 | 11 | /* solhint-disable reason-string, no-console */ 12 | 13 | contract Deploy is Script { 14 | function run() external { 15 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 16 | vm.startBroadcast(deployer); 17 | 18 | address cTokenAddr = 0xc3d688B66703497DAA19211EEdff47f25384cdc3; 19 | IRewards rewards = IRewards(0x1B0e765F6224C21223AeA2af16c1C46E38885a40); 20 | ERC20 comp = ERC20(0xc00e94Cb662C3520282E6f5717214004A7f26888); 21 | address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 22 | IUniswapV2Router02 router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); 23 | address[] memory strategists = new address[](1); 24 | strategists[0] = 0x47fD0834DD8b435BbbD7115bB7d3b3120dD0946d; 25 | 26 | AffineVault vault = AffineVault(0x84eF1F1A7f14A237c4b1DA8d13548123879FC3A9); 27 | CompoundV3Strategy strategy = new CompoundV3Strategy({ 28 | _vault: vault, 29 | _cToken: IComet(cTokenAddr), 30 | _rewards: rewards, 31 | _comp: comp, 32 | _weth: weth, 33 | _router: router, 34 | strategists: strategists 35 | }); 36 | require(strategy.vault() == vault); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /script/ConvexStrategy.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script, console2} from "forge-std/Script.sol"; 5 | 6 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 7 | 8 | import {AffineVault} from "src/vaults/AffineVault.sol"; 9 | import {ConvexStrategy} from "src/strategies/ConvexStrategy.sol"; 10 | import {ICurvePool, I3CrvMetaPoolZap} from "src/interfaces/curve.sol"; 11 | import {IConvexBooster, IConvexRewards} from "src/interfaces/convex.sol"; 12 | 13 | /* solhint-disable reason-string, no-console */ 14 | 15 | library DeployLib { 16 | function deployMim3Crv(AffineVault vault) internal returns (ConvexStrategy strategy) { 17 | strategy = new ConvexStrategy({ 18 | _vault: vault, 19 | _assetIndex: 2, 20 | _isMetaPool: true, 21 | _curvePool: ICurvePool(0x5a6A4D54456819380173272A5E8E9B9904BdF41B), 22 | _zapper: I3CrvMetaPoolZap(0xA79828DF1850E8a3A3064576f380D90aECDD3359), 23 | _convexPid: 40, 24 | strategists: _getStrategists() 25 | }); 26 | } 27 | 28 | function _getStrategists() internal pure returns (address[] memory strategists) { 29 | strategists = new address[](1); 30 | strategists[0] = 0x47fD0834DD8b435BbbD7115bB7d3b3120dD0946d; 31 | } 32 | } 33 | 34 | contract Deploy is Script { 35 | function _start() internal { 36 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 37 | vm.startBroadcast(deployer); 38 | } 39 | 40 | function runMim3Crv() external { 41 | _start(); 42 | DeployLib.deployMim3Crv(AffineVault(0x84eF1F1A7f14A237c4b1DA8d13548123879FC3A9)); 43 | } 44 | 45 | function usdEarnEth() external { 46 | _start(); 47 | ConvexStrategy strat = DeployLib.deployMim3Crv(AffineVault(0x78Bb94Feab383ccEd39766a7d6CF31dED177Ad0c)); 48 | console2.log("vault: ", address(strat.vault())); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /script/EthEntry.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; 6 | import {Script, console2} from "forge-std/Script.sol"; 7 | 8 | import {Base} from "./Base.sol"; 9 | import {Vault} from "src/vaults/Vault.sol"; 10 | import {AffineVault} from "src/vaults/AffineVault.sol"; 11 | import {DeployLib} from "./ConvexStrategy.s.sol"; 12 | 13 | /* solhint-disable reason-string, no-console */ 14 | 15 | contract Deploy is Script, Base { 16 | function deployStrategies() external { 17 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 18 | vm.startBroadcast(deployer); 19 | DeployLib.deployMim3Crv(AffineVault(0x78Bb94Feab383ccEd39766a7d6CF31dED177Ad0c)); 20 | } 21 | 22 | function run() external { 23 | // Get config info 24 | bool testnet = vm.envBool("TEST"); 25 | console2.log("test: ", testnet ? 1 : 0); 26 | bytes memory configBytes = _getConfigJson({mainnet: !testnet, layer1: true}); 27 | Base.L1Config memory config = abi.decode(configBytes, (Base.L1Config)); 28 | 29 | address governance = config.governance; 30 | address usdc = config.usdc; 31 | console2.log("usdc: %s governance: %s", usdc, governance); 32 | 33 | // Start broadcasting txs 34 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 35 | vm.startBroadcast(deployer); 36 | 37 | // Deploy implementation 38 | Vault impl = new Vault(); 39 | 40 | // Initialize proxy with correct data 41 | bytes memory initData = abi.encodeCall(Vault.initialize, (governance, usdc, "USD Earn Eth", "usdEarnEth")); 42 | ERC1967Proxy proxy = new ERC1967Proxy(address(impl), initData); 43 | 44 | // Check that values were set correctly. 45 | Vault vault = Vault(address(proxy)); 46 | require(vault.governance() == governance); 47 | require(vault.asset() == usdc); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /script/LidoLev.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; 5 | import {Script, console2} from "forge-std/Script.sol"; 6 | 7 | import {Vault} from "src/vaults/Vault.sol"; 8 | import {LidoLev} from "src/strategies/LidoLev.sol"; 9 | import {LidoLevL2} from "src/strategies/LidoLevL2.sol"; 10 | 11 | /* solhint-disable reason-string, no-console */ 12 | 13 | contract Deploy is Script { 14 | function run() external { 15 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 16 | vm.startBroadcast(deployer); 17 | 18 | address[] memory strategists = new address[](1); 19 | strategists[0] = 0x47fD0834DD8b435BbbD7115bB7d3b3120dD0946d; 20 | new LidoLev(LidoLev(payable(address(0))), 175, Vault(0x1196B60c9ceFBF02C9a3960883213f47257BecdB), strategists); 21 | } 22 | } 23 | 24 | contract DeployL2 is Script { 25 | function run() external { 26 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 27 | vm.startBroadcast(deployer); 28 | 29 | address[] memory strategists = new address[](1); 30 | strategists[0] = 0x47fD0834DD8b435BbbD7115bB7d3b3120dD0946d; 31 | LidoLevL2 strat = new LidoLevL2(Vault(0x3b07A1A5de80f9b22DE0EC6C44C6E59DDc1C5f41), strategists); 32 | 33 | require(address(strat.asset()) == 0x4200000000000000000000000000000000000006); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /script/LidoLevV3.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; 5 | import {Script, console2} from "forge-std/Script.sol"; 6 | 7 | import {Vault, AffineVault} from "src/vaults/Vault.sol"; 8 | import {LidoLevV3} from "src/strategies/LidoLevV3.sol"; 9 | import {LidoLevEthStrategy} from "src/strategies/deployed/LidoLevEthStrategy.sol"; 10 | 11 | /* solhint-disable reason-string, no-console */ 12 | 13 | contract Deploy is Script { 14 | function _start() internal { 15 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 16 | console2.log("deployer %s", deployer); 17 | vm.startBroadcast(deployer); 18 | } 19 | 20 | function run() external { 21 | _start(); 22 | 23 | Vault vault = Vault(0xF5c10746B8EE6B69A17f66eCD642d2Fb9df8fcE0); // tmp vault add 24 | address[] memory strategists = new address[](1); 25 | strategists[0] = 0x47fD0834DD8b435BbbD7115bB7d3b3120dD0946d; 26 | 27 | LidoLevV3 strategy = new LidoLevV3(AffineVault(address(vault)), strategists); 28 | 29 | console2.log("strategy add %s", address(strategy)); 30 | 31 | require(address(vault.asset()) == address(strategy.asset()), "Error: Vault asset mismatch detected."); 32 | require( 33 | address(strategy.asset()) == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, "Error: Asset mismatch detected." 34 | ); 35 | } 36 | 37 | function lidoLevEth() external { 38 | _start(); 39 | 40 | Vault vault = Vault(0x1196B60c9ceFBF02C9a3960883213f47257BecdB); // Lev eth vault 41 | address[] memory strategists = new address[](1); 42 | strategists[0] = 0x47fD0834DD8b435BbbD7115bB7d3b3120dD0946d; 43 | 44 | LidoLevEthStrategy strategy = new LidoLevEthStrategy(AffineVault(address(vault)), strategists); 45 | 46 | console2.log("strategy add %s", address(strategy)); 47 | 48 | require(address(vault.asset()) == address(strategy.asset()), "Error: Vault asset mismatch detected."); 49 | require( 50 | address(strategy.asset()) == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, "Error: Asset mismatch detected." 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /script/ReStaking.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; 5 | 6 | import {AffineReStaking} from "src/vaults/restaking/AffineReStaking.sol"; 7 | 8 | import {Script, console2} from "forge-std/Script.sol"; 9 | /* solhint-disable reason-string, no-console */ 10 | 11 | contract Deploy is Script { 12 | function _start() internal { 13 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 14 | vm.startBroadcast(deployer); 15 | console2.log("deployer address %s", deployer); 16 | } 17 | 18 | function deployReStaking() public { 19 | _start(); 20 | 21 | address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 22 | address governance = 0x4B21438ffff0f0B938aD64cD44B8c6ebB78ba56e; 23 | 24 | AffineReStaking impl = new AffineReStaking(); 25 | 26 | bytes memory initData = abi.encodeCall(AffineReStaking.initialize, (governance, weth)); 27 | ERC1967Proxy proxy = new ERC1967Proxy(address(impl), initData); 28 | AffineReStaking reStaking = AffineReStaking(address(proxy)); 29 | console2.log("ReStaking Add %s", address(reStaking)); 30 | 31 | require(address(reStaking.governance()) == governance, "Invalid gov"); 32 | require(address(reStaking.WETH()) == weth, "invalid weth"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /script/SmartWallet.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script, console2} from "forge-std/Script.sol"; 5 | 6 | import {SmartWallet} from "src/utils/SmartWallet.sol"; 7 | 8 | /* solhint-disable reason-string, no-console */ 9 | 10 | contract Deploy is Script { 11 | function run() external { 12 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 13 | vm.startBroadcast(deployer); 14 | 15 | address rahul = 0x2033a56d6215424B3389bb863261D3B44709Fb79; 16 | SmartWallet wallet = new SmartWallet(rahul); 17 | require(wallet.hasRole(wallet.OWNER(), rahul)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /script/upgrades/StrategyVaultV2.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script} from "forge-std/Script.sol"; 5 | 6 | import {DegenVaultV2, DegenVaultV2Eth, HighYieldLpVaultEth} from "src/vaults/custom/DegenVaultV2.sol"; 7 | 8 | /* solhint-disable reason-string, no-console */ 9 | 10 | contract DeployDegen is Script { 11 | function run() external { 12 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 13 | vm.startBroadcast(deployer); 14 | 15 | new DegenVaultV2(); 16 | } 17 | 18 | function runDegenEth() external { 19 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 20 | vm.startBroadcast(deployer); 21 | 22 | new DegenVaultV2Eth(); 23 | } 24 | 25 | function runHighYieldLpEth() external { 26 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 27 | vm.startBroadcast(deployer); 28 | 29 | new HighYieldLpVaultEth(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /script/upgrades/TwoAssetBasket.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script, console2} from "forge-std/Script.sol"; 5 | 6 | import {TwoAssetBasket} from "src/vaults/TwoAssetBasket.sol"; 7 | 8 | /* solhint-disable reason-string, no-console */ 9 | 10 | contract Deploy is Script { 11 | function run() external { 12 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 13 | vm.startBroadcast(deployer); 14 | 15 | TwoAssetBasket vault = new TwoAssetBasket(); 16 | console2.log("deployer address: ", deployer); 17 | console2.log("new implementation address: ", address(vault)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /script/upgrades/VaultV2.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {Script, console2} from "forge-std/Script.sol"; 5 | 6 | import {VaultV2} from "src/vaults/VaultV2.sol"; 7 | import {EthVaultV2} from "src/vaults/EthVaultV2.sol"; 8 | 9 | /* solhint-disable reason-string, no-console */ 10 | 11 | contract LevStakingV2Poly is VaultV2 {} 12 | 13 | contract LevStakingV2Eth is EthVaultV2 {} 14 | 15 | contract Deploy is Script { 16 | function run() external { 17 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 18 | vm.startBroadcast(deployer); 19 | 20 | LevStakingV2Poly vault = new LevStakingV2Poly(); 21 | console2.log("new implementation address: ", address(vault)); 22 | } 23 | 24 | function runEth() external { 25 | (address deployer,) = deriveRememberKey(vm.envString("MNEMONIC"), 0); 26 | vm.startBroadcast(deployer); 27 | 28 | LevStakingV2Eth vault = new LevStakingV2Eth(); 29 | console2.log("new implementation address: ", address(vault)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /scripts/deploy.ts: -------------------------------------------------------------------------------- 1 | import { program } from "commander"; 2 | import { execSync } from "child_process"; 3 | 4 | import { config as dotenvConfig } from "dotenv"; 5 | import { resolve } from "path"; 6 | dotenvConfig({ path: resolve(__dirname, "../.env") }); 7 | import { defenderEth, defenderPolygon } from "./utils/export"; 8 | 9 | function executeScript(options: { layer: "1" | "2"; testnet: boolean; broadcast: boolean }) { 10 | const isTest = options.testnet; 11 | const isLayer1 = options.layer === "1"; 12 | if (options.layer !== "1" && options.layer !== "2") throw Error("Invalid layer"); 13 | 14 | const ALCHEMY_ETH_KEY = (isTest ? process.env.ALCHEMY_ETH_GOERLI_KEY : process.env.ALCHEMY_ETH_MAINNET_KEY) || ""; 15 | const ALCHEMY_POLYGON_KEY = 16 | (isTest ? process.env.ALCHEMY_POLYGON_MUMBAI_KEY : process.env.ALCHEMY_POLYGON_MAINNET_KEY) || ""; 17 | 18 | const ethNet = isTest ? "goerli" : "mainnet"; 19 | const polygonNet = isTest ? "mumbai" : "mainnet"; 20 | 21 | const rpcUrl = isLayer1 22 | ? `https://eth-${ethNet}.alchemyapi.io/v2/${ALCHEMY_ETH_KEY}` 23 | : `https://polygon-${polygonNet}.g.alchemy.com/v2/${ALCHEMY_POLYGON_KEY}`; 24 | 25 | const contract = isLayer1 ? "L1.s.sol:Deploy" : "L2.s.sol:Deploy"; 26 | const broadcast = options.broadcast ? "--broadcast" : ""; 27 | const testEnv = isTest ? "true" : "false"; 28 | 29 | const scriptCommand = `TEST=${testEnv} forge script script/${contract} --rpc-url ${rpcUrl} --ffi -vvv ${broadcast}`; 30 | execSync(scriptCommand, { stdio: "inherit" }); 31 | if (isLayer1) defenderEth(!options.broadcast, isTest); 32 | else defenderPolygon(!options.broadcast, isTest); 33 | } 34 | 35 | program 36 | .requiredOption("-l, --layer ", "The layer to run the script on. Use 1 for eth and 2 for polygon") 37 | .option("-t, --testnet", "Run script on goerli/mumbai instead of eth/polygon") 38 | .option("-b, --broadcast", "Actually broadcast transactions"); 39 | 40 | program.parse(); 41 | 42 | const options = program.opts() as { layer: "1" | "2"; testnet: boolean; broadcast: boolean }; 43 | console.log({ options }); 44 | executeScript(options); 45 | -------------------------------------------------------------------------------- /scripts/doc-gen/contract.hbs: -------------------------------------------------------------------------------- 1 | {{#if natspec.notice}} 2 | ### {{name}} 3 | > {{natspec.notice}} 4 | 5 | | test function | description | 6 | | --- | --- | 7 | {{#each functions}} 8 | {{#if natspec.notice}} 9 | |`{{name}}`|{{natspec.notice}}| 10 | {{/if}} 11 | {{/each}} 12 | {{/if}} -------------------------------------------------------------------------------- /scripts/doc-gen/gen-test-doc.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { docgen } from "solidity-docgen"; 4 | import { readdir, readFile } from "node:fs/promises"; 5 | import path from "path"; 6 | import { SourceUnit } from "solidity-ast"; 7 | import { SolcOutput } from "solidity-ast/solc"; 8 | 9 | type SolcOutputUnit = { 10 | ast: SourceUnit; 11 | id: number; 12 | }; 13 | 14 | const main = async () => { 15 | const outputDir = "./out"; 16 | const solcOutput: SolcOutput = { sources: {} }; 17 | const dirs = await readdir(outputDir); 18 | for (let dirName of dirs) { 19 | if (!dirName.endsWith(".t.sol")) continue; 20 | const dirFiles = await readdir(path.join(outputDir, dirName), { withFileTypes: true }); 21 | for (const f of dirFiles) { 22 | if (f.isDirectory()) continue; 23 | const content = JSON.parse((await readFile(path.join(outputDir, dirName, f.name))).toString()) as SolcOutputUnit; 24 | const fName = f.name.replace(".json", ".sol"); 25 | solcOutput.sources[fName] = content; 26 | } 27 | } 28 | await docgen([{ input: { sources: {} }, output: solcOutput }], { 29 | sourcesDir: "src/test", 30 | outputDir: "docs/tests", 31 | templates: "scripts/doc-gen", 32 | }); 33 | }; 34 | 35 | main() 36 | .then(() => process.exit(0)) 37 | .catch(error => { 38 | console.error(error); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /scripts/doc-gen/page.hbs: -------------------------------------------------------------------------------- 1 | # Affine Tests 2 | {{#each items}} 3 | {{#hsection}} 4 | {{>item}} 5 | {{/hsection}} 6 | 7 | {{/each}} -------------------------------------------------------------------------------- /scripts/utils/constants/blockchain.ts: -------------------------------------------------------------------------------- 1 | import { BlockchainInfo } from "./types"; 2 | import { ethChainIds, polygonChainIds } from "./types"; 3 | enum blockchains { 4 | ETHEREUM = "Ethereum", 5 | POYLGON = "Polygon", 6 | } 7 | 8 | enum ethNetworks { 9 | MAINNET = "Mainnet", 10 | GOERLI = "Goerli", 11 | } 12 | 13 | enum polygonNetworks { 14 | MAINNET = "Matic", 15 | MUMBAI = "Mumbai", 16 | } 17 | 18 | enum proofFormats { 19 | POA = "POA", 20 | POS = "POS", 21 | POW = "POW", 22 | } 23 | 24 | export const ETH_GOERLI: BlockchainInfo = { 25 | name: blockchains.ETHEREUM, 26 | network: ethNetworks.GOERLI, 27 | network_id: ethChainIds.goerli, 28 | proof_format: proofFormats.POA, 29 | } as const; 30 | 31 | export const ETH_MAINNET: BlockchainInfo = { 32 | name: blockchains.ETHEREUM, 33 | network: ethNetworks.MAINNET, 34 | network_id: ethChainIds.mainnet, 35 | proof_format: proofFormats.POW, 36 | } as const; 37 | 38 | export const POLYGON_MUMBAI: BlockchainInfo = { 39 | name: blockchains.POYLGON, 40 | network: polygonNetworks.MUMBAI, 41 | network_id: polygonChainIds.mumbai, 42 | proof_format: proofFormats.POS, 43 | } as const; 44 | 45 | export const POLYGON_MAINNET: BlockchainInfo = { 46 | name: blockchains.POYLGON, 47 | network: polygonNetworks.MAINNET, 48 | network_id: polygonChainIds.mainnet, 49 | proof_format: proofFormats.POS, 50 | } as const; 51 | -------------------------------------------------------------------------------- /scripts/utils/constants/types.ts: -------------------------------------------------------------------------------- 1 | export interface BlockchainInfo { 2 | name: string; 3 | network: string; 4 | network_id: number; 5 | proof_format: string; 6 | } 7 | 8 | export const ethChainIds = { 9 | ganache: 1337, 10 | goerli: 5, 11 | hardhat: 31337, 12 | kovan: 42, 13 | mainnet: 1, 14 | rinkeby: 4, 15 | ropsten: 3, 16 | }; 17 | export type ethNetwork = keyof typeof ethChainIds; 18 | 19 | export const polygonChainIds = { 20 | mainnet: 137, 21 | mumbai: 80001, 22 | }; 23 | export type polygonNetwork = keyof typeof polygonChainIds; 24 | -------------------------------------------------------------------------------- /scripts/utils/defender-client.ts: -------------------------------------------------------------------------------- 1 | import { AdminClient } from "defender-admin-client"; 2 | 3 | const defenderAPIKey = process.env.DEFENDER_API_KEY || ""; 4 | const defenderAPISecret = process.env.DEFENDER_API_SECRET || ""; 5 | 6 | const defenderClient = new AdminClient({ apiKey: defenderAPIKey, apiSecret: defenderAPISecret }); 7 | 8 | export default defenderClient; 9 | -------------------------------------------------------------------------------- /scripts/utils/get-bytes.ts: -------------------------------------------------------------------------------- 1 | import crypto from "crypto"; 2 | 3 | process.stdout.write(crypto.randomBytes(32).toString("hex")); 4 | -------------------------------------------------------------------------------- /scripts/utils/types.ts: -------------------------------------------------------------------------------- 1 | export type address = string; 2 | -------------------------------------------------------------------------------- /scripts/utils/wormhole.ts: -------------------------------------------------------------------------------- 1 | import { getSignedVAA, getEmitterAddressEth, ChainId } from "@certusone/wormhole-sdk"; 2 | import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"; 3 | import { BigNumber } from "ethers"; 4 | 5 | export async function sleep(ms: number) { 6 | return new Promise(f => setTimeout(f, ms)); 7 | } 8 | 9 | export async function attemptGettingVAA( 10 | wormholeAPIURL: string, 11 | emitter: string, 12 | sequence: BigNumber, 13 | emitterChain: ChainId, 14 | ) { 15 | try { 16 | const result = await getSignedVAA(wormholeAPIURL, emitterChain, getEmitterAddressEth(emitter), String(sequence), { 17 | transport: NodeHttpTransport(), 18 | }); 19 | return result.vaaBytes; 20 | } catch (e) { 21 | return undefined; 22 | } 23 | } 24 | 25 | export async function getVAA(emitter: string, sequence: string, emitterChain: number, maxAttempts = 64) { 26 | let result; 27 | let attempts = 0; 28 | while (!result) { 29 | console.log("waiting for VAA"); 30 | attempts += 1; 31 | await sleep(60000); 32 | 33 | try { 34 | result = await getSignedVAA( 35 | "https://wormhole-v2-testnet-api.certus.one", 36 | emitterChain as ChainId, 37 | getEmitterAddressEth(emitter), 38 | sequence, 39 | { 40 | transport: NodeHttpTransport(), 41 | }, 42 | ); 43 | } catch (e) { 44 | if (attempts > maxAttempts) throw e; 45 | } 46 | } 47 | return result.vaaBytes; 48 | } 49 | -------------------------------------------------------------------------------- /slither.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "detectors_to_exclude": "naming-convention", 3 | "filter_paths": "src/test|src/testnet|src/interfaces|node_modules", 4 | "ignore_compile": "true", 5 | "hardhat_cache_directory": "hh-cache" 6 | } 7 | -------------------------------------------------------------------------------- /src/interfaces/AggregatorV3Interface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | interface AggregatorV3Interface { 5 | function decimals() external view returns (uint8); 6 | 7 | function description() external view returns (string memory); 8 | 9 | function version() external view returns (uint256); 10 | 11 | // getRoundData and latestRoundData should both raise "No data present" 12 | // if they do not have data to report, instead of returning unset values 13 | // which could be misinterpreted as actual reported values. 14 | function getRoundData(uint80 _roundId) 15 | external 16 | view 17 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); 18 | 19 | function latestRoundData() 20 | external 21 | view 22 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); 23 | } 24 | -------------------------------------------------------------------------------- /src/interfaces/ICreate3Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity >=0.8.0; 3 | 4 | /// @title Factory for deploying contracts to deterministic addresses via CREATE3 5 | /// @author zefram.eth 6 | /// @notice Enables deploying contracts using CREATE3. Each deployer (msg.sender) has 7 | /// its own namespace for deployed addresses. 8 | interface ICREATE3Factory { 9 | /// @notice Deploys a contract using CREATE3 10 | /// @dev The provided salt is hashed together with msg.sender to generate the final salt 11 | /// @param salt The deployer-specific salt for determining the deployed contract's address 12 | /// @param creationCode The creation code of the contract to deploy 13 | /// @return deployed The address of the deployed contract 14 | function deploy(bytes32 salt, bytes memory creationCode) external payable returns (address deployed); 15 | 16 | /// @notice Predicts the address of a deployed contract 17 | /// @dev The provided salt is hashed together with the deployer address to generate the final salt 18 | /// @param deployer The deployer account that will call deploy() 19 | /// @param salt The deployer-specific salt for determining the deployed contract's address 20 | /// @return deployed The address of the contract that will be deployed 21 | function getDeployed(address deployer, bytes32 salt) external view returns (address deployed); 22 | } 23 | -------------------------------------------------------------------------------- /src/interfaces/IPearl.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IRouter} from "./pearl/IRouter.sol"; 5 | import {IPair} from "./pearl/IPair.sol"; 6 | -------------------------------------------------------------------------------- /src/interfaces/IRootChainManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | interface IRootChainManager { 5 | function depositFor(address user, address rootToken, bytes calldata depositData) external; 6 | 7 | function exit(bytes memory _data) external; 8 | } 9 | -------------------------------------------------------------------------------- /src/interfaces/IUniPositionValue.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {INonfungiblePositionManager} from "@uniswap/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol"; 5 | 6 | interface IUniPositionValue { 7 | function total(INonfungiblePositionManager positionManager, uint256 tokenId, uint160 sqrtRatioX96) 8 | external 9 | view 10 | returns (uint256 amount0, uint256 amount1); 11 | 12 | function principal(INonfungiblePositionManager positionManager, uint256 tokenId, uint160 sqrtRatioX96) 13 | external 14 | view 15 | returns (uint256 amount0, uint256 amount1); 16 | 17 | function fees(INonfungiblePositionManager positionManager, uint256 tokenId) 18 | external 19 | view 20 | returns (uint256 amount0, uint256 amount1); 21 | } 22 | -------------------------------------------------------------------------------- /src/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 5 | 6 | interface IWETH is IERC20Metadata { 7 | function deposit() external payable; 8 | function transfer(address to, uint256 value) external returns (bool); 9 | function withdraw(uint256) external; 10 | } 11 | -------------------------------------------------------------------------------- /src/interfaces/IWormhole.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | interface IWormhole { 5 | struct Signature { 6 | bytes32 r; 7 | bytes32 s; 8 | uint8 v; 9 | uint8 guardianIndex; 10 | } 11 | 12 | struct VM { 13 | uint8 version; 14 | uint32 timestamp; 15 | uint32 nonce; 16 | uint16 emitterChainId; 17 | bytes32 emitterAddress; 18 | uint64 sequence; 19 | uint8 consistencyLevel; 20 | bytes payload; 21 | uint32 guardianSetIndex; 22 | Signature[] signatures; 23 | bytes32 hash; 24 | } 25 | 26 | function publishMessage(uint32 nonce, bytes memory payload, uint8 consistencyLevel) 27 | external 28 | payable 29 | returns (uint64 sequence); 30 | 31 | function parseAndVerifyVM(bytes calldata encodedVM) 32 | external 33 | view 34 | returns (VM memory vm, bool valid, string memory reason); 35 | 36 | function nextSequence(address emitter) external view returns (uint64); 37 | } 38 | -------------------------------------------------------------------------------- /src/interfaces/aave.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ILendingPoolAddressesProvider} from "./aave/ILendingPoolAddressesProvider.sol"; 5 | import {IAaveIncentivesController} from "./aave/IAaveIncentivesController.sol"; 6 | import {ILendingPool} from "./aave/ILendingPool.sol"; 7 | import {IAToken} from "./aave/IAToken.sol"; 8 | import {ILendingPoolAddressesProviderRegistry} from "./aave/ILendingPoolAddressesProviderRegistry.sol"; 9 | import {IProtocolDataProvider} from "./aave/IProtocolDataProvider.sol"; 10 | -------------------------------------------------------------------------------- /src/interfaces/aave/DataTypes.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | library DataTypes { 5 | // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. 6 | struct ReserveData { 7 | //stores the reserve configuration 8 | ReserveConfigurationMap configuration; 9 | //the liquidity index. Expressed in ray 10 | uint128 liquidityIndex; 11 | //variable borrow index. Expressed in ray 12 | uint128 variableBorrowIndex; 13 | //the current supply rate. Expressed in ray 14 | uint128 currentLiquidityRate; 15 | //the current variable borrow rate. Expressed in ray 16 | uint128 currentVariableBorrowRate; 17 | //the current stable borrow rate. Expressed in ray 18 | uint128 currentStableBorrowRate; 19 | uint40 lastUpdateTimestamp; 20 | //tokens addresses 21 | address aTokenAddress; 22 | address stableDebtTokenAddress; 23 | address variableDebtTokenAddress; 24 | //address of the interest rate strategy 25 | address interestRateStrategyAddress; 26 | //the id of the reserve. Represents the position in the list of the active reserves 27 | uint8 id; 28 | } 29 | 30 | struct ReserveConfigurationMap { 31 | //bit 0-15: LTV 32 | //bit 16-31: Liq. threshold 33 | //bit 32-47: Liq. bonus 34 | //bit 48-55: Decimals 35 | //bit 56: Reserve is active 36 | //bit 57: reserve is frozen 37 | //bit 58: borrowing is enabled 38 | //bit 59: stable rate borrowing enabled 39 | //bit 60-63: reserved 40 | //bit 64-79: reserve factor 41 | uint256 data; 42 | } 43 | 44 | struct UserConfigurationMap { 45 | uint256 data; 46 | } 47 | 48 | enum InterestRateMode { 49 | NONE, 50 | STABLE, 51 | VARIABLE 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/interfaces/aave/IAaveIncentivesController.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /* solhint-disable func-name-mixedcase */ 5 | interface IAaveIncentivesController { 6 | /** 7 | * @dev Returns the total of rewards of an user, already accrued + not yet accrued 8 | * @param user The address of the user 9 | * @return The rewards 10 | * 11 | */ 12 | function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256); 13 | 14 | /** 15 | * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards 16 | * @param amount Amount of rewards to claim 17 | * @param to Address that will be receiving the rewards 18 | * @return Rewards claimed 19 | * 20 | */ 21 | function claimRewards(address[] calldata assets, uint256 amount, address to) external returns (uint256); 22 | 23 | /** 24 | * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must 25 | * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager 26 | * @param amount Amount of rewards to claim 27 | * @param user Address to check and claim rewards 28 | * @param to Address that will be receiving the rewards 29 | * @return Rewards claimed 30 | * 31 | */ 32 | function claimRewardsOnBehalf(address[] calldata assets, uint256 amount, address user, address to) 33 | external 34 | returns (uint256); 35 | 36 | /** 37 | * @dev returns the unclaimed rewards of the user 38 | * @param user the address of the user 39 | * @return the unclaimed user rewards 40 | */ 41 | function getUserUnclaimedRewards(address user) external view returns (uint256); 42 | 43 | /** 44 | * @dev for backward compatibility with previous implementation of the Incentives controller 45 | */ 46 | function REWARD_TOKEN() external view returns (address); 47 | 48 | function getDistributionEnd() external view returns (uint256); 49 | 50 | function getAssetData(address asset) external view returns (uint256, uint256, uint256); 51 | } 52 | -------------------------------------------------------------------------------- /src/interfaces/aave/ILendingPoolAddressesProviderRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /** 5 | * @title LendingPoolAddressesProviderRegistry contract 6 | * @dev Main registry of LendingPoolAddressesProvider of multiple Aave protocol's markets 7 | * - Used for indexing purposes of Aave protocol's markets 8 | * - The id assigned to a LendingPoolAddressesProvider refers to the market it is connected with, 9 | * for example with `0` for the Aave main market and `1` for the next created 10 | * @author Aave 11 | * 12 | */ 13 | interface ILendingPoolAddressesProviderRegistry { 14 | event AddressesProviderRegistered(address indexed newAddress); 15 | event AddressesProviderUnregistered(address indexed newAddress); 16 | 17 | function getAddressesProvidersList() external view returns (address[] memory); 18 | 19 | function getAddressesProviderIdByAddress(address addressesProvider) external view returns (uint256); 20 | 21 | function registerAddressesProvider(address provider, uint256 id) external; 22 | 23 | function unregisterAddressesProvider(address provider) external; 24 | } 25 | -------------------------------------------------------------------------------- /src/interfaces/aave/IScaledBalanceToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | interface IScaledBalanceToken { 5 | /** 6 | * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the 7 | * updated stored balance divided by the reserve's liquidity index at the moment of the update 8 | * @param user The user whose balance is calculated 9 | * @return The scaled balance of the user 10 | * 11 | */ 12 | function scaledBalanceOf(address user) external view returns (uint256); 13 | 14 | /** 15 | * @dev Returns the scaled balance of the user and the scaled total supply. 16 | * @param user The address of the user 17 | * @return The scaled balance of the user 18 | * @return The scaled balance and the scaled total supply 19 | * 20 | */ 21 | function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); 22 | 23 | /** 24 | * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index) 25 | * @return The scaled total supply 26 | * 27 | */ 28 | function scaledTotalSupply() external view returns (uint256); 29 | } 30 | -------------------------------------------------------------------------------- /src/interfaces/aerodrome.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IAeroRouter} from "./aerodrome/IAeroRouter.sol"; 5 | import {IAeroPool} from "./aerodrome/IAeroPool.sol"; 6 | -------------------------------------------------------------------------------- /src/interfaces/balancer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IFlashLoanRecipient} from "src/interfaces/balancer/IFlashLoanRecipient.sol"; 5 | import {IBalancerVault} from "src/interfaces/balancer/IBalancerVault.sol"; 6 | import {IBalancerQueries} from "src/interfaces/balancer/IBalancerQueries.sol"; 7 | -------------------------------------------------------------------------------- /src/interfaces/balancer/IBalancerQueries.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IBalancerVault} from "./IBalancerVault.sol"; 5 | 6 | interface IBalancerQueries { 7 | function querySwap(IBalancerVault.SingleSwap memory singleSwap, IBalancerVault.FundManagement memory funds) 8 | external 9 | returns (uint256); 10 | } 11 | -------------------------------------------------------------------------------- /src/interfaces/balancer/IFlashLoanRecipient.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | interface IFlashLoanRecipient { 7 | /** 8 | * @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient. 9 | * 10 | * At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this 11 | * call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the 12 | * Vault, or else the entire flash loan will revert. 13 | * 14 | * `userData` is the same value passed in the `IVault.flashLoan` call. 15 | */ 16 | function receiveFlashLoan( 17 | ERC20[] memory tokens, 18 | uint256[] memory amounts, 19 | uint256[] memory feeAmounts, 20 | bytes memory userData 21 | ) external; 22 | } 23 | -------------------------------------------------------------------------------- /src/interfaces/compound.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ICToken} from "src/interfaces/compound/ICToken.sol"; 5 | import {IComptroller} from "src/interfaces/compound/IComptroller.sol"; 6 | -------------------------------------------------------------------------------- /src/interfaces/compound/ICToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 5 | 6 | /// @dev This is used for both CEtherand CErc20 tokens 7 | interface ICToken is IERC20 { 8 | function borrow(uint256) external returns (uint256); 9 | 10 | function borrowRatePerBlock() external view returns (uint256); 11 | 12 | function borrowBalanceCurrent(address) external returns (uint256); 13 | 14 | function repayBorrow(uint256) external returns (uint256); 15 | function repayBorrow() external payable; 16 | 17 | function mint(uint256 underlying) external payable returns (uint256); 18 | function mint() external payable; 19 | 20 | function redeemUnderlying(uint256) external returns (uint256); 21 | 22 | function balanceOfUnderlying(address) external returns (uint256); 23 | 24 | function exchangeRateCurrent() external returns (uint256); 25 | } 26 | -------------------------------------------------------------------------------- /src/interfaces/compound/IComptroller.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ICToken} from "./ICToken.sol"; 5 | 6 | interface IComptroller { 7 | function claimComp(address holder, ICToken[] memory cTokens) external; 8 | 9 | // @dev different for strike finance 10 | function claimStrike(address holder) external; 11 | function claimStrike(address holder, ICToken[] memory cTokens) external; 12 | 13 | function compAccrued(address) external view returns (uint256); 14 | 15 | function markets(address) external returns (bool, uint256); 16 | 17 | function enterMarkets(address[] calldata) external returns (uint256[] memory); 18 | 19 | function getAccountLiquidity(address) external view returns (uint256, uint256, uint256); 20 | } 21 | -------------------------------------------------------------------------------- /src/interfaces/compound/IRewards.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {CometStructs} from "./IComet.sol"; 5 | 6 | // @dev See https://github.com/compound-developers/compound-3-developer-faq/blob/61eccdeb3155a53e180bb5689d2afb4c1f36908f/contracts/MyContract.sol#LL90C1-L93C2 7 | interface IRewards { 8 | function getRewardOwed(address comet, address account) external returns (CometStructs.RewardOwed memory); 9 | function claim(address comet, address src, bool shouldAccrue) external; 10 | } 11 | -------------------------------------------------------------------------------- /src/interfaces/convex.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IConvexBooster} from "./convex/IConvexBooster.sol"; 5 | import {IConvexRewards} from "./convex/IConvexRewards.sol"; 6 | -------------------------------------------------------------------------------- /src/interfaces/convex/IConvexBooster.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // See https://docs.convexfinance.com/convexfinanceintegration/booster 5 | 6 | interface IConvexBooster { 7 | struct PoolInfo { 8 | address lptoken; 9 | address token; 10 | address gauge; 11 | address crvRewards; 12 | address stash; 13 | bool shutdown; 14 | } 15 | 16 | function poolLength() external returns (uint256); 17 | function poolInfo(uint256 _pid) external returns (PoolInfo memory); 18 | function depositAll(uint256 _pid, bool _stake) external returns (bool); 19 | function crv() external returns (address); 20 | } 21 | -------------------------------------------------------------------------------- /src/interfaces/convex/IConvexRewards.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // See https://docs.convexfinance.com/convexfinanceintegration/baserewardpool 5 | interface IConvexRewards { 6 | // get balance of an address 7 | function balanceOf(address _account) external returns (uint256); 8 | //withdraw to a convex tokenized deposit 9 | function withdraw(uint256 _amount, bool _claim) external returns (bool); 10 | //withdraw directly to curve LP token 11 | function withdrawAndUnwrap(uint256 amount, bool claim) external returns (bool); 12 | // Withdraw to curve LP token while also claiming any rewards 13 | function withdrawAllAndUnwrap(bool claim) external; 14 | // claim rewards 15 | function getReward() external returns (bool); 16 | //stake a convex tokenized deposit 17 | function stake(uint256 _amount) external returns (bool); 18 | //stake a convex tokenized deposit for another address(transferring ownership) 19 | function stakeFor(address _account, uint256 _amount) external returns (bool); 20 | 21 | // Get amount of pending CRV rewards 22 | function earned(address account) external view returns (uint256); 23 | } 24 | -------------------------------------------------------------------------------- /src/interfaces/curve.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ICurvePool} from "./curve/ICurvePool.sol"; 5 | import {ILiquidityGauge} from "./curve/ILiquidityGauge.sol"; 6 | import {I3CrvMetaPoolZap} from "./curve/IMetaPoolZap.sol"; 7 | import {IMinter} from "./curve/IMinter.sol"; 8 | -------------------------------------------------------------------------------- /src/interfaces/curve/ICurvePool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // See https://curve.readthedocs.io/exchange-deposits.html#curve-stableswap-exchange-deposit-contracts 5 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 6 | 7 | interface ICurvePool { 8 | function lp_token() external view returns (address); 9 | 10 | function add_liquidity(uint256[2] memory depositAmounts, uint256 minMintAmount) 11 | external 12 | payable 13 | returns (uint256); 14 | 15 | function remove_liquidity_one_coin(uint256 _burn_amount, int128 i, uint256 _min_amount) 16 | external 17 | returns (uint256); 18 | 19 | function remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount) 20 | external 21 | returns (uint256); 22 | 23 | function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256); 24 | function get_virtual_price() external view returns (uint256); 25 | function exchange(int128 x, int128 y, uint256 dx, uint256 min_dy) external returns (uint256); 26 | // `uint` is used on base 27 | function exchange(uint256 x, uint256 y, uint256 dx, uint256 min_dy) external returns (uint256); 28 | } 29 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 30 | -------------------------------------------------------------------------------- /src/interfaces/curve/ILiquidityGauge.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // See https://etherscan.io/address/0xd8b712d29381748dB89c36BCa0138d7c75866ddF#code 5 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 6 | interface ILiquidityGauge { 7 | function deposit(uint256 _value) external; 8 | function withdraw(uint256 _value) external returns (uint256); 9 | function balanceOf(address owner) external returns (uint256); 10 | 11 | // Get claimable CRV 12 | function claimable_tokens(address addr) external returns (uint256); 13 | function claim_rewards() external; 14 | 15 | // NOTE: The below only applies to non-CRV rewards 16 | // claimable_reward - claimed_reward = pending rewards 17 | // Total rewards, claimed and unclaimed 18 | function claimable_reward(address addr, address token) external view returns (uint256); 19 | // unclaimed 20 | function claimed_reward(address addr, address token) external view returns (uint256); 21 | } 22 | 23 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 24 | -------------------------------------------------------------------------------- /src/interfaces/curve/IMetaPoolZap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // See https://etherscan.io/address/0xa79828df1850e8a3a3064576f380d90aecdd3359#code for an example 5 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 6 | interface I3CrvMetaPoolZap { 7 | function add_liquidity(address pool, uint256[4] memory depositAmounts, uint256 minMintAmount) 8 | external 9 | returns (uint256); 10 | 11 | function remove_liquidity_one_coin(address pool, uint256 burnAmount, int128 index, uint256 minAmount) 12 | external 13 | returns (uint256); 14 | 15 | function remove_liquidity_imbalance(address _pool, uint256[4] memory _amounts, uint256 _maxBurnAmount) 16 | external 17 | returns (uint256); 18 | 19 | function calc_withdraw_one_coin(address pool, uint256 tokenAmount, int128 index) external view returns (uint256); 20 | function calc_token_amount(address pool, uint256[4] memory amounts, bool deposit) external view returns (uint256); 21 | } 22 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 23 | -------------------------------------------------------------------------------- /src/interfaces/curve/IMinter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // See https://etherscan.io/address/0xd061D61a4d941c39E5453435B6345Dc261C2fcE0#code 5 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 6 | interface IMinter { 7 | function mint(address gauge) external; 8 | } 9 | 10 | /* solhint-disable func-name-mixedcase, var-name-mixedcase */ 11 | -------------------------------------------------------------------------------- /src/interfaces/eigenlayer/eigen.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | struct WithdrawalInfo { 5 | address staker; 6 | address delegatedTo; 7 | address withdrawer; 8 | uint256 nonce; 9 | uint32 startBlock; 10 | address[] strategies; 11 | uint256[] shares; 12 | } 13 | 14 | struct QueuedWithdrawalParams { 15 | address[] strategies; 16 | uint256[] shares; 17 | address recipient; 18 | } 19 | 20 | struct ApproverSignatureAndExpiryParams { 21 | bytes signature; 22 | uint256 expiry; 23 | } 24 | 25 | interface IDelegationManager { 26 | function delegateTo(address, ApproverSignatureAndExpiryParams calldata, bytes32) external; 27 | function queueWithdrawals(QueuedWithdrawalParams[] calldata) external returns (bytes32[] memory); 28 | function completeQueuedWithdrawals( 29 | WithdrawalInfo[] calldata, 30 | address[][] calldata, 31 | uint256[] calldata, 32 | bool[] calldata 33 | ) external; 34 | function calculateWithdrawalRoot(WithdrawalInfo memory withdrawal) external pure returns (bytes32); 35 | function pendingWithdrawals(bytes32) external view returns (bool); 36 | /** 37 | * @notice returns the address of the operator that `staker` is delegated to. 38 | * @notice Mapping: staker => operator whom the staker is currently delegated to. 39 | * @dev Note that returning address(0) indicates that the staker is not actively delegated to any operator. 40 | */ 41 | function delegatedTo(address staker) external view returns (address); 42 | } 43 | 44 | interface IStrategyManager { 45 | function depositIntoStrategy(address, address, uint256) external; 46 | } 47 | 48 | interface IStrategy { 49 | function underlyingToShares(uint256) external view returns (uint256); 50 | function sharesToUnderlying(uint256) external view returns (uint256); 51 | function userUnderlyingView(address) external view returns (uint256); 52 | function sharesToUnderlyingView(uint256) external view returns (uint256); 53 | function shares(address) external view returns (uint256); 54 | } 55 | -------------------------------------------------------------------------------- /src/interfaces/lido/IStEth.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface IStEth is IERC20 { 7 | function submit(address _referral) external payable returns (uint256); 8 | function getTotalPooledEther() external view returns (uint256); 9 | function getTotalShares() external view returns (uint256); 10 | function sharesOf(address _account) external view returns (uint256); 11 | function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); 12 | function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); 13 | function transferShares(address _recipient, uint256 _sharesAmount) external returns (uint256); 14 | function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) 15 | external 16 | returns (uint256); 17 | } 18 | -------------------------------------------------------------------------------- /src/interfaces/lido/IWSTETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | abstract contract IWSTETH is ERC20 { 7 | function unwrap(uint256 _wstETHAmount) external virtual returns (uint256); 8 | function wrap(uint256 _stETHAmount) external virtual returns (uint256); 9 | function getStETHByWstETH(uint256 _wstETHAmount) external view virtual returns (uint256); 10 | function getWstETHByStETH(uint256 _stETHAmount) external view virtual returns (uint256); 11 | function stEthPerToken() external view virtual returns (uint256); 12 | function tokensPerStEth() external view virtual returns (uint256); 13 | } 14 | -------------------------------------------------------------------------------- /src/interfaces/maker.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ICdpManager} from "./maker/ICdpManager.sol"; 5 | import {ICropper} from "./maker/IMakerAdapter.sol"; 6 | import {IVat} from "./maker/IVat.sol"; 7 | import {IGemJoin} from "./maker/IGemJoin.sol"; 8 | -------------------------------------------------------------------------------- /src/interfaces/maker/ICdpManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // https://github.com/makerdao/dss-cdp-manager/ 5 | // dss-interfaces 6 | interface ICdpManager { 7 | function vat() external view returns (address); 8 | function cdpi() external view returns (uint256); 9 | function urns(uint256) external view returns (address); 10 | function list(uint256) external view returns (uint256, uint256); 11 | function owns(uint256) external view returns (address); 12 | function ilks(uint256) external view returns (bytes32); 13 | function first(address) external view returns (uint256); 14 | function last(address) external view returns (uint256); 15 | function count(address) external view returns (uint256); 16 | function cdpCan(address, uint256, address) external returns (uint256); 17 | function urnCan(address, address) external returns (uint256); 18 | function cdpAllow(uint256, address, uint256) external; 19 | function urnAllow(address, uint256) external; 20 | function open(bytes32, address) external returns (uint256); 21 | function give(uint256, address) external; 22 | function frob(uint256, int256, int256) external; 23 | function flux(uint256 cdp, address dst, uint256 wad) external; 24 | function flux(bytes32, uint256, address, uint256) external; 25 | function move(uint256 cdp, address dst, uint256 rad) external; 26 | function quit(uint256, address) external; 27 | function enter(address, uint256) external; 28 | function shift(uint256, uint256) external; 29 | } 30 | -------------------------------------------------------------------------------- /src/interfaces/maker/IGemJoin.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // https://github.com/makerdao/dss/blob/master/src/join.sol 5 | interface IGemJoin { 6 | function wards(address) external view returns (uint256); 7 | function rely(address) external; 8 | function deny(address) external; 9 | function vat() external view returns (address); 10 | function ilk() external view returns (bytes32); 11 | function gem() external view returns (address); 12 | function dec() external view returns (uint256); 13 | function live() external view returns (uint256); 14 | function cage() external; 15 | function join(address usr, uint256 wad) external; 16 | function exit(address, uint256) external; 17 | } 18 | -------------------------------------------------------------------------------- /src/interfaces/maker/IMakerAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // See MCD_CROPPER at https://etherscan.io/address/0x8377CD01a5834a6EaD3b7efb482f678f2092b77e#code 5 | // Crop is MCD_JOIN_CRVV1ETHSTETH_A 6 | interface ICropper { 7 | function join(address crop, address usr, uint256 val) external; 8 | function frob(bytes32 ilk, address u, address v, address w, int256 dink, int256 dart) external; 9 | function move(address u, address dst, uint256 rad) external; 10 | function flux(address crop, address src, address dst, uint256 wad) external; 11 | function exit(address crop, address usr, uint256 val) external; 12 | function proxy(address user) external returns (address urn); 13 | } 14 | 15 | interface IMakerAdapter { 16 | // See https://github.com/makerdao/dss-crop-join/blob/master/src/CropJoin.sol 17 | // at https://github.com/makerdao/dss-interfaces/blob/9bfd7afadd1f8c217ef05850b2555691786286cb/src/dss/DaiJoinAbstract.sol 18 | function join(address urn, address usr, uint256 val) external; 19 | function exit(address usr, uint256 val) external; 20 | } 21 | -------------------------------------------------------------------------------- /src/interfaces/maker/IVat.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | // https://github.com/makerdao/dss/blob/master/src/vat.sol 5 | /* solhint-disable func-name-mixedcase */ 6 | interface IVat { 7 | function wards(address) external view returns (uint256); 8 | function rely(address) external; 9 | function deny(address) external; 10 | function can(address, address) external view returns (uint256); 11 | function hope(address) external; 12 | function nope(address) external; 13 | function ilks(bytes32) external view returns (uint256, uint256, uint256, uint256, uint256); 14 | function urns(bytes32, address) external view returns (uint256, uint256); 15 | function gem(bytes32, address) external view returns (uint256); 16 | function dai(address) external view returns (uint256); 17 | function sin(address) external view returns (uint256); 18 | function debt() external view returns (uint256); 19 | function vice() external view returns (uint256); 20 | function Line() external view returns (uint256); 21 | function live() external view returns (uint256); 22 | function init(bytes32) external; 23 | function file(bytes32, uint256) external; 24 | function file(bytes32, bytes32, uint256) external; 25 | function cage() external; 26 | function slip(bytes32, address, int256) external; 27 | function flux(bytes32, address, address, uint256) external; 28 | function move(address, address, uint256) external; 29 | function frob(bytes32, address, address, address, int256, int256) external; 30 | function fork(bytes32, address, address, int256, int256) external; 31 | function grab(bytes32, address, address, address, int256, int256) external; 32 | function heal(uint256) external; 33 | function suck(address, address, uint256) external; 34 | function fold(bytes32, address, int256) external; 35 | } 36 | -------------------------------------------------------------------------------- /src/interfaces/pearl/IPair.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 5 | 6 | interface IPair is IERC20Metadata { 7 | function initialize(address _token0, address _token1, bool _stable) external; 8 | 9 | function metadata() 10 | external 11 | view 12 | returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, bool st, address t0, address t1); 13 | 14 | function claimFees() external returns (uint256, uint256); 15 | 16 | function tokens() external view returns (address, address); 17 | 18 | function token0() external view returns (address); 19 | 20 | function token1() external view returns (address); 21 | 22 | function transferFrom(address src, address dst, uint256 amount) external returns (bool); 23 | 24 | function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) 25 | external; 26 | 27 | function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; 28 | 29 | function burn(address to) external returns (uint256 amount0, uint256 amount1); 30 | 31 | function mint(address to) external returns (uint256 liquidity); 32 | 33 | function getReserves() external view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast); 34 | 35 | function getAmountOut(uint256, address) external view returns (uint256); 36 | 37 | function name() external view returns (string memory); 38 | 39 | function symbol() external view returns (string memory); 40 | 41 | function totalSupply() external view returns (uint256); 42 | 43 | function decimals() external view returns (uint8); 44 | 45 | function claimable0(address _user) external view returns (uint256); 46 | 47 | function claimable1(address _user) external view returns (uint256); 48 | 49 | function stable() external view returns (bool); 50 | } 51 | -------------------------------------------------------------------------------- /src/interfaces/permit2/IEIP712.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | interface IEIP712 { 5 | function DOMAIN_SEPARATOR() external view returns (bytes32); 6 | } 7 | -------------------------------------------------------------------------------- /src/interfaces/permit2/IPermit2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ISignatureTransfer} from "./ISignatureTransfer.sol"; 5 | import {IAllowanceTransfer} from "./IAllowanceTransfer.sol"; 6 | 7 | /// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer. 8 | /// @dev Users must approve Permit2 before calling any of the transfer functions. 9 | interface IPermit2 is ISignatureTransfer, IAllowanceTransfer { 10 | // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval. 11 | } 12 | -------------------------------------------------------------------------------- /src/interfaces/sushiswap/IMasterChef.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 5 | 6 | interface IMasterChef { 7 | struct UserInfo { 8 | uint256 amount; // How many LP tokens the user has provided. 9 | uint256 rewardDebt; // Reward debt. See explanation below. 10 | } 11 | 12 | struct PoolInfo { 13 | IERC20 lpToken; // Address of LP token contract. 14 | uint256 allocPoint; // How many allocation points assigned to this pool. SUSHI to distribute per block. 15 | uint256 lastRewardBlock; // Last block number that SUSHI distribution occurs. 16 | uint256 accSushiPerShare; // Accumulated SUSHI per share, times 1e12. See below. 17 | } 18 | 19 | function poolLength() external view returns (uint256); 20 | function poolInfo(uint256 pid) external view returns (IMasterChef.PoolInfo memory); 21 | function userInfo(uint256 pid, address user) external view returns (IMasterChef.UserInfo memory); 22 | function totalAllocPoint() external view returns (uint256); 23 | function deposit(uint256 _pid, uint256 _amount) external; 24 | function withdraw(uint256 _pid, uint256 _amount) external; 25 | // V2 26 | 27 | struct PoolInfoV2 { 28 | uint256 allocPoint; // How many allocation points assigned to this pool. SUSHI to distribute per block. 29 | uint256 lastRewardTime; // Timestamp when SUSHI distribution occurred. 30 | uint256 accSushiPerShare; // Accumulated SUSHI per share, times 1e12. See below. 31 | } 32 | 33 | function deposit(uint256 _pid, uint256 _amount, address _to) external; 34 | function withdrawAndHarvest(uint256 _pid, uint256 _amount, address _to) external; 35 | function updatePool(uint256 _pid) external returns (IMasterChef.PoolInfoV2 memory); 36 | function harvest(uint256 pid, address to) external; 37 | function pendingSushi(uint256 _pid, address _user) external view returns (uint256 pending); 38 | } 39 | -------------------------------------------------------------------------------- /src/libs/ReStakingErrors.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | library ReStakingErrors { 5 | error AlreadyApprovedToken(); 6 | error NotApprovedToken(); 7 | error DepositAmountCannotBeZero(); 8 | error CannotDepositForZeroAddress(); 9 | error TokenNotAllowedForStaking(); 10 | error WithdrawAmountCannotBeZero(); 11 | error InvalidWithdrawalAmount(); 12 | error ExceedsDepositLimit(); 13 | error ExceedsMintLimit(); 14 | error ExceedsWithdrawLimit(); 15 | error ExceedsRedeemLimit(); 16 | error InsufficientLiquidAssets(); 17 | error ExistingEscrowDebt(); 18 | error InvalidEscrowVault(); 19 | error ExceedsDelegatorWithdrawableAssets(); 20 | error ExceedsMaxDelegatorLimit(); 21 | error NonZeroEmptyDelegatorTVL(); 22 | error InactiveDelegator(); 23 | error RequireHarvest(); 24 | error ProfitUnlocking(); 25 | error DepositPaused(); 26 | error InvalidDelegatorFactory(); 27 | error RunningEpoch(); 28 | error NoResolvingEpoch(); 29 | error MaxUnresolvedEpochReached(); 30 | error InvalidEscrow(); 31 | } 32 | -------------------------------------------------------------------------------- /src/libs/VaultErrors.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | library VaultErrors { 5 | error ZeroShares(); 6 | error ProfitUnlocking(); 7 | error SharesExceedBalance(); 8 | error OnlyWormholeRouter(); 9 | error OnlyEscrow(); 10 | error TooManyStrategyBps(); 11 | error TvlLimitReached(); 12 | } 13 | -------------------------------------------------------------------------------- /src/libs/audited/Constants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 22 Line 10 | * Extended: False 11 | */ 12 | library Constants { 13 | // Message types 14 | // Messages received by L1 15 | bytes32 constant L2_FUND_TRANSFER_REPORT = keccak256("L2_FUND_TRANSFER_REPORT"); 16 | bytes32 constant L2_FUND_REQUEST = keccak256("L2_FUND_REQUEST"); 17 | 18 | // Messages received by L2 19 | bytes32 constant L1_TVL = keccak256("L1_TVL"); 20 | bytes32 constant L1_FUND_TRANSFER_REPORT = keccak256("L1_FUND_TRANSFER_REPORT"); 21 | } 22 | -------------------------------------------------------------------------------- /src/libs/audited/DollarMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 31 Line 10 | * Extended: False 11 | */ 12 | type Dollar is uint256; 13 | 14 | library DollarMath { 15 | function add(Dollar a, Dollar b) internal pure returns (Dollar) { 16 | return Dollar.wrap(Dollar.unwrap(a) + Dollar.unwrap(b)); 17 | } 18 | 19 | function sub(Dollar a, Dollar b) internal pure returns (Dollar) { 20 | return Dollar.wrap(Dollar.unwrap(a) - Dollar.unwrap(b)); 21 | } 22 | 23 | function mul(Dollar a, Dollar b) internal pure returns (Dollar) { 24 | return Dollar.wrap(Dollar.unwrap(a) * Dollar.unwrap(b)); 25 | } 26 | 27 | function div(Dollar a, Dollar b) internal pure returns (Dollar) { 28 | return Dollar.wrap(Dollar.unwrap(a) / Dollar.unwrap(b)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/libs/audited/SlippageUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 27 Line 10 | * Extended: False 11 | */ 12 | import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol"; 13 | 14 | library SlippageUtils { 15 | using FixedPointMathLib for uint256; 16 | 17 | uint256 constant MAX_BPS = 10_000; 18 | 19 | function slippageUp(uint256 amount, uint256 slippageBps) internal pure returns (uint256) { 20 | return amount.mulDivDown(MAX_BPS + slippageBps, MAX_BPS); 21 | } 22 | 23 | function slippageDown(uint256 amount, uint256 slippageBps) internal pure returns (uint256) { 24 | return amount.mulDivUp(MAX_BPS - slippageBps, MAX_BPS); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/libs/audited/Unchecked.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 18 Line 10 | * Extended: False 11 | */ 12 | 13 | /* solhint-disable func-visibility */ 14 | function uncheckedInc(uint256 i) pure returns (uint256) { 15 | unchecked { 16 | return i + 1; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/strategies/AccessStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; 5 | 6 | import {AffineVault} from "src/vaults/AffineVault.sol"; 7 | import {BaseStrategy} from "src/strategies/audited/BaseStrategy.sol"; 8 | import {uncheckedInc} from "src/libs/audited/Unchecked.sol"; 9 | 10 | contract AccessStrategy is BaseStrategy, AccessControl { 11 | bytes32 public constant STRATEGIST_ROLE = keccak256("STRATEGIST"); 12 | 13 | constructor(AffineVault _vault, address[] memory strategists) BaseStrategy(_vault) { 14 | // Governance is admin 15 | _grantRole(DEFAULT_ADMIN_ROLE, vault.governance()); 16 | _grantRole(STRATEGIST_ROLE, vault.governance()); 17 | 18 | // Give STRATEGIST_ROLE to every address in list 19 | for (uint256 i = 0; i < strategists.length; i = uncheckedInc(i)) { 20 | _grantRole(STRATEGIST_ROLE, strategists[i]); 21 | } 22 | } 23 | 24 | function totalLockedValue() external virtual override returns (uint256) { 25 | return 0; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/strategies/BeefyEpochStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | import {ICurvePool, I3CrvMetaPoolZap} from "src/interfaces/curve.sol"; 7 | import {IBeefyVault} from "src/interfaces/Beefy.sol"; 8 | 9 | import {AccessStrategy} from "src/strategies/AccessStrategy.sol"; 10 | 11 | import {AffineVault} from "src/vaults/Vault.sol"; 12 | 13 | import {BeefyStrategy} from "src/strategies/BeefyStrategy.sol"; 14 | import {StrategyVault} from "src/vaults/locked/StrategyVault.sol"; 15 | 16 | contract BeefyEpochStrategy is BeefyStrategy { 17 | StrategyVault public immutable sVault; 18 | 19 | constructor( 20 | StrategyVault _vault, 21 | ICurvePool _pool, 22 | I3CrvMetaPoolZap _zapper, 23 | int128 _assetIndex, 24 | IBeefyVault _beefy, 25 | address[] memory strategists 26 | ) BeefyStrategy(AffineVault(address(_vault)), _pool, _zapper, _assetIndex, _beefy, strategists) { 27 | sVault = _vault; 28 | } 29 | 30 | function endEpoch() external onlyRole(STRATEGIST_ROLE) { 31 | sVault.endEpoch(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/strategies/SSVDeltaNeutralLp.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {StrategyVault} from "src/vaults/locked/StrategyVault.sol"; 5 | import {AffineVault} from "src/vaults/AffineVault.sol"; 6 | import {DeltaNeutralLp, LpInfo, LendingInfo} from "src/strategies/DeltaNeutralLp.sol"; 7 | 8 | contract SSVDeltaNeutralLp is DeltaNeutralLp { 9 | StrategyVault public immutable strategyVault; 10 | 11 | constructor( 12 | StrategyVault _vault, 13 | LendingInfo memory lendingInfo, 14 | LpInfo memory lpInfo, 15 | address[] memory strategists 16 | ) DeltaNeutralLp(AffineVault(address(_vault)), lendingInfo, lpInfo, strategists) { 17 | strategyVault = _vault; 18 | } 19 | 20 | function startPosition(uint256 assets, uint256 slippageToleranceBps) external override onlyRole(STRATEGIST_ROLE) { 21 | _startPosition(assets, slippageToleranceBps); 22 | strategyVault.beginEpoch(); 23 | } 24 | 25 | function endPosition(uint256 slippageToleranceBps) external override onlyRole(STRATEGIST_ROLE) { 26 | _endPosition(slippageToleranceBps); 27 | strategyVault.endEpoch(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/strategies/deployed/LidoLevEthStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {AffineVault} from "src/vaults/AffineVault.sol"; 5 | import {LidoLevV3} from "src/strategies/LidoLevV3.sol"; 6 | 7 | ///@dev deployed on 12/01/2023 8 | /** 9 | * Vault eth lev eth staking 10 | * Strategy info: Lido Lev eth using aave and balancer flash loan 11 | * withdrawal requires curve to swap steth to eth 12 | * vault address: 0x1196B60c9ceFBF02C9a3960883213f47257BecdB 13 | */ 14 | contract LidoLevEthStrategy is LidoLevV3 { 15 | constructor(AffineVault _vault, address[] memory strategists) LidoLevV3(_vault, strategists) {} 16 | } 17 | -------------------------------------------------------------------------------- /src/test/AaveV3Strategy.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | import {TestPlus} from "./TestPlus.sol"; 7 | import {stdStorage, StdStorage} from "forge-std/Test.sol"; 8 | import {Deploy} from "./Deploy.sol"; 9 | 10 | import {AffineVault} from "src/vaults/AffineVault.sol"; 11 | import {BridgeEscrow} from "src/vaults/cross-chain-vault/escrow/audited/BridgeEscrow.sol"; 12 | import {AaveV3Strategy, IPool} from "src/strategies/AaveV3Strategy.sol"; 13 | 14 | import {AAVEStratTest} from "./AaveV2Strategy.t.sol"; 15 | 16 | /// @notice Test AAVE strategy 17 | contract BaseAaveStratTest is AAVEStratTest { 18 | function _fork() internal override { 19 | forkBase(); 20 | } 21 | 22 | function _usdc() internal override returns (address) { 23 | return 0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA; 24 | } 25 | 26 | function _lendingPool() internal override returns (address) { 27 | return 0xA238Dd80C259a72e81d7e4664a9801593F98d1c5; 28 | } 29 | 30 | function _deployStrategy() internal override returns (address strat) { 31 | strat = address(new AaveV3Strategy(vault, IPool(_lendingPool()))); 32 | } 33 | } 34 | 35 | contract BaseAaveStratL2Test is AAVEStratTest { 36 | function _fork() internal override { 37 | vm.createSelectFork("polygon", 54_537_000); 38 | } 39 | 40 | function _usdc() internal override returns (address) { 41 | return 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174; 42 | } 43 | 44 | function _lendingPool() internal override returns (address) { 45 | return 0x794a61358D6845594F94dc1DB02A252b5b4814aD; 46 | } 47 | 48 | function _deployStrategy() internal override returns (address strat) { 49 | strat = address(new AaveV3Strategy(vault, IPool(_lendingPool()))); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/BaseStrategy.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | import {TestPlus} from "./TestPlus.sol"; 7 | import {stdStorage, StdStorage} from "forge-std/Test.sol"; 8 | import {Deploy} from "./Deploy.sol"; 9 | import {MockERC20} from "./mocks/MockERC20.sol"; 10 | 11 | import {TestStrategy} from "./mocks/TestStrategy.sol"; 12 | 13 | import {BaseVault} from "src/vaults/cross-chain-vault/audited/BaseVault.sol"; 14 | import {AffineVault} from "src/vaults/AffineVault.sol"; 15 | 16 | /// @notice Test general functionalities of strategies. 17 | contract BaseStrategyTest is TestPlus { 18 | TestStrategy strategy; 19 | MockERC20 rewardToken; 20 | 21 | function setUp() public { 22 | rewardToken = new MockERC20("Mock Token", "MT", 18); 23 | BaseVault vault = Deploy.deployL2Vault(); 24 | strategy = new TestStrategy(AffineVault(address(vault))); 25 | } 26 | 27 | /// @notice Test only governance can sweep tokens from vaults. 28 | function testSweep() public { 29 | // Will revert if non governance tries to call it 30 | vm.expectRevert("BS: only governance"); 31 | vm.startPrank(alice); // vitalik 32 | strategy.sweep(rewardToken); 33 | 34 | vm.startPrank(governance); 35 | // award the strategy some tokens 36 | rewardToken.mint(address(strategy), 1e18); 37 | strategy.sweep(rewardToken); 38 | 39 | // Governance addr received reward tokens 40 | assertEq(rewardToken.balanceOf(governance), 1e18); 41 | assertEq(rewardToken.balanceOf(address(strategy)), 0); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/CREATE3Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {CREATE3} from "solmate/src/utils/CREATE3.sol"; 5 | 6 | import {ICREATE3Factory} from "src/interfaces/ICreate3Factory.sol"; 7 | 8 | /// @title Factory for deploying contracts to deterministic addresses via CREATE3 9 | /// @author zefram.eth 10 | /// @notice Enables deploying contracts using CREATE3. Each deployer (msg.sender) has 11 | /// its own namespace for deployed addresses. 12 | contract CREATE3Factory is ICREATE3Factory { 13 | /// @inheritdoc ICREATE3Factory 14 | function deploy(bytes32 salt, bytes memory creationCode) external payable override returns (address deployed) { 15 | // hash salt with the deployer address to give each deployer its own namespace 16 | salt = keccak256(abi.encodePacked(msg.sender, salt)); 17 | return CREATE3.deploy(salt, creationCode, msg.value); 18 | } 19 | 20 | /// @inheritdoc ICREATE3Factory 21 | function getDeployed(address deployer, bytes32 salt) external view override returns (address deployed) { 22 | // hash salt with the deployer address to give each deployer its own namespace 23 | salt = keccak256(abi.encodePacked(deployer, salt)); 24 | return CREATE3.getDeployed(salt); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/ConvertLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | library ConvertLib { 5 | function toString(address account) public pure returns (string memory) { 6 | return toString(abi.encodePacked(account)); 7 | } 8 | 9 | function toString(uint256 value) public pure returns (string memory) { 10 | return toString(abi.encodePacked(value)); 11 | } 12 | 13 | function toString(bytes32 value) public pure returns (string memory) { 14 | return toString(abi.encodePacked(value)); 15 | } 16 | 17 | function toString(bytes memory data) public pure returns (string memory) { 18 | bytes memory alphabet = "0123456789abcdef"; 19 | 20 | bytes memory str = new bytes(2 + data.length * 2); 21 | str[0] = "0"; 22 | str[1] = "x"; 23 | for (uint256 i = 0; i < data.length; ++i) { 24 | str[2 + i * 2] = alphabet[uint256(uint8(data[i] >> 4))]; 25 | str[3 + i * 2] = alphabet[uint256(uint8(data[i] & 0x0f))]; 26 | } 27 | return string(str); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/Create3Deployer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {CREATE3} from "solmate/src/utils/CREATE3.sol"; 5 | 6 | contract Create3Deployer { 7 | function deploy(bytes32 salt, bytes memory creationCode, uint256 value) external returns (address deployed) { 8 | deployed = CREATE3.deploy(salt, creationCode, value); 9 | } 10 | 11 | function getDeployed(bytes32 salt) external view returns (address) { 12 | return CREATE3.getDeployed(salt); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/EthVault.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {TestPlus} from "./TestPlus.sol"; 5 | import {stdStorage, StdStorage} from "forge-std/Test.sol"; 6 | 7 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 8 | 9 | import {EthVault} from "src/vaults/EthVault.sol"; 10 | 11 | contract EthVaultTest is TestPlus { 12 | EthVault vault; 13 | ERC20 asset; 14 | 15 | function setUp() public { 16 | forkEth(); 17 | 18 | asset = ERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); 19 | vault = new EthVault(); 20 | vault.initialize(governance, address(asset), "Eth Earn", "ethEarn"); 21 | } 22 | 23 | function testWithdrawEth() public { 24 | // Give alice 1 share (in vault's decimals) 25 | uint256 shares = 10 ** vault.decimals(); 26 | deal(address(vault), alice, shares, true); 27 | // Give vault 1 WETH 28 | deal(vault.asset(), address(vault), 1e18); 29 | 30 | // Alice withdraws 1 ether 31 | vm.prank(alice); 32 | vault.withdraw(1 ether, alice, alice); 33 | 34 | // Alice receives 1 ether and has no shares or WETH 35 | assertEq(alice.balance, 1 ether); 36 | assertEq(asset.balanceOf(alice), 0); 37 | assertEq(vault.balanceOf(alice), 0); 38 | } 39 | /// @notice Test redeem eth 40 | 41 | function testRedeemEth() public { 42 | // Give alice 1 share (in vault's decimals) 43 | uint256 shares = 10 ** vault.decimals(); 44 | deal(address(vault), alice, shares, true); 45 | // Give vault 1 WETH 46 | deal(vault.asset(), address(vault), 1e18); 47 | 48 | // Alice withdraws 1 ether 49 | vm.prank(alice); 50 | vault.redeem(shares, alice, alice); 51 | 52 | // Alice receives 1 ether and has no shares or WETH 53 | assertEq(alice.balance, 1 ether); 54 | assertEq(asset.balanceOf(alice), 0); 55 | assertEq(vault.balanceOf(alice), 0); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/L2VaultV2.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {L2VaultV2} from "src/vaults/cross-chain-vault/L2VaultV2.sol"; 5 | import {RebalanceModule} from "src/vaults/cross-chain-vault/RebalanceModule.sol"; 6 | 7 | import {L2VaultTest, AffineVault, Deploy, MockL2Vault} from "./L2Vault.t.sol"; 8 | 9 | import {BaseStrategy, TestStrategy} from "./mocks/TestStrategy.sol"; 10 | 11 | contract L2VaultV2Test is L2VaultTest { 12 | function _deployVault() internal override { 13 | vault = MockL2Vault(address(Deploy.deployL2VaultV2())); 14 | } 15 | 16 | /// @notice Test internal rebalancing of vault. 17 | function testRebalance() public { 18 | BaseStrategy strat1 = new TestStrategy(AffineVault(address(vault))); 19 | BaseStrategy strat2 = new TestStrategy(AffineVault(address(vault))); 20 | 21 | vm.startPrank(governance); 22 | vault.addStrategy(strat1, 6000); 23 | vault.addStrategy(strat2, 4000); 24 | vm.stopPrank(); 25 | 26 | // strat1 should have 6000 and strat2 should have 4000. Since we switch the numbers, calling `rebalance` 27 | // will move 2000 of `asset` from strat2 to strat1 28 | asset.mint(address(strat1), 4000); 29 | asset.mint(address(strat2), 6000); 30 | 31 | // Harvest 32 | BaseStrategy[] memory strategies = new BaseStrategy[](2); 33 | strategies[0] = strat1; 34 | strategies[1] = strat2; 35 | vm.warp(vault.lastHarvest() + vault.LOCK_INTERVAL() + 1); 36 | vm.prank(governance); // gov has all roles 37 | vault.harvest(strategies); 38 | 39 | vm.startPrank(governance); 40 | RebalanceModule module = new RebalanceModule(); 41 | L2VaultV2(address(vault)).setRebalanceModule(address(module)); 42 | vault.grantRole(vault.HARVESTER(), address(module)); 43 | vault.rebalance(); 44 | vm.stopPrank(); 45 | 46 | assertTrue(asset.balanceOf(address(strat1)) == 6000); 47 | assertTrue(asset.balanceOf(address(strat2)) == 4000); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/SmartWallet.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {TestPlus} from "./TestPlus.sol"; 5 | import {stdStorage, StdStorage} from "forge-std/Test.sol"; 6 | 7 | import {MockERC20} from "./mocks/MockERC20.sol"; 8 | 9 | import {SmartWallet} from "src/utils/SmartWallet.sol"; 10 | 11 | contract SmartWalletTest is TestPlus { 12 | MockERC20 asset1; 13 | MockERC20 asset2; 14 | SmartWallet wallet; 15 | 16 | function setUp() public { 17 | asset1 = new MockERC20("Mock", "MT", 6); 18 | asset2 = new MockERC20("Mock", "MT", 6); 19 | 20 | wallet = new SmartWallet(address(this)); 21 | 22 | asset1.mint(address(wallet), 10); 23 | asset2.mint(address(wallet), 20); 24 | } 25 | 26 | function testMultiCall() public { 27 | SmartWallet.Call memory call1 = 28 | SmartWallet.Call({target: address(asset1), callData: abi.encodeCall(asset1.transfer, (address(0), 10))}); 29 | SmartWallet.Call memory call2 = 30 | SmartWallet.Call({target: address(asset2), callData: abi.encodeCall(asset2.transfer, (address(0), 20))}); 31 | 32 | SmartWallet.Call[] memory calls = new SmartWallet.Call[](2); 33 | calls[0] = call1; 34 | calls[1] = call2; 35 | wallet.aggregate(calls); 36 | 37 | assertEq(asset1.balanceOf(address(wallet)), 0); 38 | assertEq(asset1.balanceOf(address(0)), 10); 39 | 40 | assertEq(asset2.balanceOf(address(wallet)), 0); 41 | assertEq(asset2.balanceOf(address(0)), 20); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/TestPlus.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {Test} from "forge-std/Test.sol"; 5 | import {stdStorage, StdStorage} from "forge-std/Test.sol"; 6 | import {Vm} from "forge-std/Vm.sol"; 7 | import {console2} from "forge-std/console2.sol"; 8 | 9 | import {Deploy} from "./Deploy.sol"; 10 | 11 | contract TestPlus is Test, Deploy { 12 | using stdStorage for StdStorage; 13 | 14 | address alice = makeAddr("alice"); 15 | address bob = makeAddr("bob"); 16 | address charlie = makeAddr("charlie"); 17 | 18 | uint256 constant ETH_FORK_BLOCK = 16_897_451; 19 | uint256 constant POLYGON_FORK_BLOCK = 38_961_333; 20 | 21 | function forkEth() internal { 22 | vm.createSelectFork("ethereum", ETH_FORK_BLOCK); 23 | } 24 | 25 | function forkPolygon() internal { 26 | vm.createSelectFork("polygon", POLYGON_FORK_BLOCK); 27 | } 28 | 29 | function forkArb() internal { 30 | vm.createSelectFork("arbitrum", 124_531_545); 31 | } 32 | 33 | function forkBase() internal { 34 | vm.createSelectFork("base", 3_584_744); 35 | } 36 | 37 | function assertInRange(uint256 a, uint256 b1, uint256 b2) internal { 38 | if (a < b1 || a > b2) { 39 | emit log("Error: a in range [b1, b2] not satisfied [uint]"); 40 | emit log_named_uint("Expected b1", b1); 41 | emit log_named_uint("Expected b2", b2); 42 | emit log_named_uint(" Actual", a); 43 | fail(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/integration/SSVDeltaNeutral.int.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | import {TestPlus} from "src/test/TestPlus.sol"; 6 | import {console2} from "forge-std/console2.sol"; 7 | 8 | import {SSVDeltaNeutralLp} from "src/strategies/SSVDeltaNeutralLp.sol"; 9 | import {StrategyVault} from "src/vaults/locked/StrategyVault.sol"; 10 | import {WithdrawalEscrow} from "src/vaults/locked/WithdrawalEscrow.sol"; 11 | 12 | import {SSV} from "script/TestStrategyVault.s.sol"; 13 | 14 | contract SSVDeltaNeutralLp__IntegrationTest is TestPlus { 15 | SSVDeltaNeutralLp strategy; 16 | StrategyVault vault; 17 | WithdrawalEscrow escrow; 18 | 19 | uint256 startBlock = 17_168_737; 20 | 21 | ERC20 asset; 22 | 23 | function setUp() public { 24 | vm.createSelectFork("ethereum", startBlock); 25 | strategy = SSVDeltaNeutralLp(0x4306c088Fa31fE77dA9F513Ea31823E877417243); 26 | vault = StrategyVault(address(strategy.vault())); 27 | asset = ERC20(vault.asset()); 28 | } 29 | 30 | function testBalances() public { 31 | console2.log("asset", asset.balanceOf(address(vault))); 32 | 33 | vm.rollFork(startBlock - 1); 34 | console2.log("asset", asset.balanceOf(address(vault))); 35 | 36 | vm.rollFork(17_146_481); 37 | console2.log("asset", asset.balanceOf(address(vault))); 38 | 39 | vm.rollFork(17_145_511); 40 | console2.log("asset", asset.balanceOf(address(vault))); 41 | 42 | vm.rollFork(17_141_159); 43 | console2.log("asset", asset.balanceOf(address(vault))); 44 | 45 | vm.rollFork(17_141_158); 46 | console2.log("asset", asset.balanceOf(address(vault))); 47 | 48 | vm.rollFork(15_537_393); 49 | console2.log("asset", asset.balanceOf(address(vault))); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/integration/Storage.int.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import "forge-std/console2.sol"; 5 | import {StorageSlot} from "@openzeppelin/contracts/utils/StorageSlot.sol"; 6 | import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; 7 | import {TestPlus} from "../TestPlus.sol"; 8 | 9 | contract DegenImplTest is TestPlus { 10 | bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; 11 | 12 | // function setUp() public { 13 | // forkPolygon(); 14 | // } 15 | 16 | function testImpl() public { 17 | vm.createSelectFork("polygon", 42_754_895); 18 | address degenVault = 0x684D1dbd30c67Fe7fF6D502A04e0E7076b4b9D46; 19 | bytes32 implBytes = vm.load(degenVault, _IMPLEMENTATION_SLOT); 20 | 21 | address implAddr = address(uint160(uint256(implBytes))); 22 | console2.log("impl", implAddr); 23 | } 24 | 25 | function testImplEth() public { 26 | // The proxy was deployed at block 17239298 27 | vm.createSelectFork("ethereum", 17_239_298 + 1); 28 | address degenVault = 0x9d39ba71f30f44FB72e7b45151C27079C2cd8ECa; 29 | bytes32 implBytes = vm.load(degenVault, _IMPLEMENTATION_SLOT); 30 | 31 | address implAddr = address(uint160(uint256(implBytes))); 32 | console2.log("impl", implAddr); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/integration/VaultV2.int.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {CommonVaultTest, ERC20} from "src/test/CommonVault.t.sol"; 5 | import {Vault} from "src/vaults/Vault.sol"; 6 | import {VaultV2} from "src/vaults/VaultV2.sol"; 7 | 8 | import "forge-std/console2.sol"; 9 | 10 | abstract contract VaultV2_IntegrationTest is CommonVaultTest { 11 | function _fork() internal virtual {} 12 | 13 | function _vault() internal virtual returns (address) {} 14 | 15 | function setUp() public virtual override { 16 | _fork(); 17 | 18 | VaultV2 impl = new VaultV2(); 19 | vault = VaultV2(_vault()); 20 | 21 | governance = vault.governance(); 22 | vm.prank(governance); 23 | vault.upgradeTo(address(impl)); 24 | asset = ERC20(vault.asset()); 25 | } 26 | 27 | function _giveAssets(address user, uint256 assets) internal override { 28 | uint256 currBal = asset.balanceOf(user); 29 | deal(address(asset), address(user), currBal + assets); 30 | } 31 | } 32 | 33 | contract SthEthLevPolygon_IntegrationTest is VaultV2_IntegrationTest { 34 | function _fork() internal override { 35 | vm.createSelectFork("polygon", 45_620_526); 36 | } 37 | 38 | function _vault() internal override returns (address) { 39 | return 0xa92B1D196F0Df5F17215698f5de99eED26B659bF; 40 | } 41 | } 42 | 43 | contract StEthLev_IntegrationTest is VaultV2_IntegrationTest { 44 | function _fork() internal override { 45 | vm.createSelectFork("ethereum", 17_791_940); 46 | } 47 | 48 | function _vault() internal override returns (address) { 49 | return 0x1196B60c9ceFBF02C9a3960883213f47257BecdB; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/mocks/MockERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | contract MockERC20 is ERC20 { 7 | constructor(string memory _name, string memory _symbol, uint8 _decimals) ERC20(_name, _symbol, _decimals) {} 8 | 9 | function mint(address to, uint256 value) public virtual { 10 | _mint(to, value); 11 | } 12 | 13 | function burn(address from, uint256 value) public virtual { 14 | _burn(from, value); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/mocks/TestStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {BaseStrategy} from "src/strategies/audited/BaseStrategy.sol"; 5 | import {AffineVault} from "src/vaults/AffineVault.sol"; 6 | import {MockERC20} from "./MockERC20.sol"; 7 | 8 | contract TestStrategy is BaseStrategy { 9 | constructor(AffineVault _vault) BaseStrategy(_vault) {} 10 | 11 | function _divest(uint256 amount) internal virtual override returns (uint256) { 12 | uint256 amountToSend = amount > balanceOfAsset() ? balanceOfAsset() : amount; 13 | asset.transfer(address(vault), amountToSend); 14 | return amountToSend; 15 | } 16 | 17 | function totalLockedValue() public view override returns (uint256) { 18 | return balanceOfAsset(); 19 | } 20 | } 21 | 22 | contract TestStrategyDivestSlippage is TestStrategy { 23 | constructor(AffineVault _vault) TestStrategy(_vault) {} 24 | 25 | function _divest(uint256 amount) internal virtual override returns (uint256) { 26 | uint256 amountToSend = amount > balanceOfAsset() ? balanceOfAsset() : amount; 27 | asset.transfer(address(vault), amountToSend / 2); 28 | return amountToSend; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/mocks/foo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/src/test/mocks/foo.js -------------------------------------------------------------------------------- /src/test/mocks/index.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {L1Vault} from "src/vaults/cross-chain-vault/audited/L1Vault.sol"; 5 | import {L2Vault} from "src/vaults/cross-chain-vault/audited/L2Vault.sol"; 6 | import {L2VaultV2} from "src/vaults/cross-chain-vault/L2VaultV2.sol"; 7 | import {BridgeEscrow} from "src/vaults/cross-chain-vault/escrow/audited/BridgeEscrow.sol"; 8 | import "src/vaults/TwoAssetBasket.sol"; 9 | 10 | // Mocks needed to update variables that are in packed slots (forge-std cannot write to packed slots yet) 11 | contract MockL2Vault is L2Vault { 12 | function setCanTransferToL1(bool _can) external { 13 | canTransferToL1 = _can; 14 | } 15 | 16 | function setCanRequestFromL1(bool _can) external { 17 | canRequestFromL1 = _can; 18 | } 19 | 20 | function setMockRebalanceDelta(uint256 _rebalanceDelta) external { 21 | rebalanceDelta = uint224(_rebalanceDelta); 22 | } 23 | } 24 | 25 | contract MockL2VaultV2 is L2VaultV2 { 26 | function setCanTransferToL1(bool _can) external { 27 | canTransferToL1 = _can; 28 | } 29 | 30 | function setCanRequestFromL1(bool _can) external { 31 | canRequestFromL1 = _can; 32 | } 33 | 34 | function setMockRebalanceDelta(uint256 _rebalanceDelta) external { 35 | rebalanceDelta = uint224(_rebalanceDelta); 36 | } 37 | } 38 | 39 | contract MockL1Vault is L1Vault {} 40 | -------------------------------------------------------------------------------- /src/testnet/DummyEpochStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | import {MockERC20} from "./MockERC20.sol"; 6 | import {BaseStrategy} from "src/strategies/audited/BaseStrategy.sol"; 7 | import {AccessStrategy} from "src/strategies/AccessStrategy.sol"; 8 | import {StrategyVault} from "src/vaults/locked/StrategyVault.sol"; 9 | import {AffineVault} from "src/vaults/AffineVault.sol"; 10 | 11 | /// @notice Dummy strategy which does nothing. 12 | contract DummyEpochStrategy is AccessStrategy { 13 | StrategyVault public immutable sVault; 14 | 15 | constructor(StrategyVault _vault, address[] memory strategists) 16 | AccessStrategy(AffineVault(address(_vault)), strategists) 17 | { 18 | sVault = StrategyVault(address(_vault)); 19 | ERC20(sVault.asset()).approve(address(_vault), type(uint256).max); 20 | } 21 | 22 | function beginEpoch() external onlyRole(STRATEGIST_ROLE) { 23 | sVault.beginEpoch(); 24 | } 25 | 26 | function endEpoch() external onlyRole(STRATEGIST_ROLE) { 27 | sVault.endEpoch(); 28 | } 29 | 30 | /// @notice Updates the tvl. 31 | /// @dev We could simply call `endEpoch` repeatedly to udpate the tvl, but that would lead to misleading events. 32 | function beginAndEndEpoch() external onlyRole(STRATEGIST_ROLE) { 33 | sVault.beginEpoch(); 34 | sVault.endEpoch(); 35 | } 36 | 37 | function totalLockedValue() external view override returns (uint256) { 38 | return asset.balanceOf(address(this)); 39 | } 40 | 41 | function _divest(uint256 amount) internal virtual override returns (uint256) { 42 | uint256 amountToSend = amount > balanceOfAsset() ? balanceOfAsset() : amount; 43 | asset.transfer(address(vault), amountToSend); 44 | return amountToSend; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/testnet/MockERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | 6 | contract MockERC20 is ERC20 { 7 | constructor(string memory _name, string memory _symbol, uint8 _decimals) ERC20(_name, _symbol, _decimals) {} 8 | 9 | function mint(address to, uint256 value) public virtual { 10 | _mint(to, value); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/testnet/MockEpochStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 5 | import {MockERC20} from "./MockERC20.sol"; 6 | import {BaseStrategy} from "src/strategies/audited/BaseStrategy.sol"; 7 | import {AccessStrategy} from "src/strategies/AccessStrategy.sol"; 8 | import {StrategyVault} from "src/vaults/locked/StrategyVault.sol"; 9 | import {AffineVault} from "src/vaults/AffineVault.sol"; 10 | 11 | contract MockEpochStrategy is AccessStrategy { 12 | StrategyVault public immutable sVault; 13 | 14 | constructor(StrategyVault _vault, address[] memory strategists) 15 | AccessStrategy(AffineVault(address(_vault)), strategists) 16 | { 17 | sVault = StrategyVault(address(_vault)); 18 | ERC20(sVault.asset()).approve(address(_vault), type(uint256).max); 19 | } 20 | 21 | function beginEpoch() external onlyRole(STRATEGIST_ROLE) { 22 | sVault.beginEpoch(); 23 | } 24 | 25 | function endEpoch() external onlyRole(STRATEGIST_ROLE) { 26 | MockERC20(address(asset)).mint(address(this), 10 ** asset.decimals()); 27 | sVault.endEpoch(); 28 | } 29 | 30 | function mint(uint256 amount) external onlyRole(STRATEGIST_ROLE) { 31 | MockERC20(address(asset)).mint(address(this), amount * 10 ** asset.decimals()); 32 | } 33 | 34 | function totalLockedValue() external view override returns (uint256) { 35 | return asset.balanceOf(address(this)); 36 | } 37 | 38 | function _divest(uint256 amount) internal virtual override returns (uint256) { 39 | uint256 amountToSend = amount > balanceOfAsset() ? balanceOfAsset() : amount; 40 | asset.transfer(address(vault), amountToSend); 41 | return amountToSend; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/utils/SmartWallet.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; 5 | 6 | import {uncheckedInc} from "src/libs/audited/Unchecked.sol"; 7 | 8 | /* solhint-disable avoid-low-level-calls */ 9 | contract SmartWallet is AccessControl { 10 | bytes32 public constant OWNER = keccak256("OWNER"); 11 | 12 | constructor(address owner) { 13 | _grantRole(DEFAULT_ADMIN_ROLE, owner); 14 | _grantRole(OWNER, owner); 15 | } 16 | 17 | struct Call { 18 | address target; 19 | bytes callData; 20 | } 21 | 22 | function aggregate(Call[] memory calls) external onlyRole(OWNER) { 23 | for (uint256 i = 0; i < calls.length; i++) { 24 | (bool success,) = calls[i].target.call(calls[i].callData); 25 | require(success, "CALL_FAILED"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/audited/AffineGovernable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 27 Line 10 | * Extended: No 11 | * Changes: None 12 | */ 13 | contract AffineGovernable { 14 | /// @notice The governance address 15 | address public governance; 16 | 17 | modifier onlyGovernance() { 18 | _onlyGovernance(); 19 | _; 20 | } 21 | 22 | function _onlyGovernance() internal view { 23 | require(msg.sender == governance, "Only Governance."); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/utils/audited/Detailed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 38 Line 10 | * Extended: False 11 | */ 12 | abstract contract DetailedShare { 13 | /** 14 | * @notice A representation of a floating point number. 15 | * `decimals` is the number of digits before the where the decimal point would be placeds 16 | */ 17 | struct Number { 18 | uint256 num; 19 | uint8 decimals; 20 | } 21 | 22 | /// @notice The tvl is a dollar amount representing the total value locked in the vault. 23 | function detailedTVL() external virtual returns (Number memory); 24 | 25 | /** 26 | * @notice The number of dollars that "one" share is worth. 27 | * @dev "One" share is always 1 * 10 ^ (decimals). Note that `decimals` refers 28 | * to the ERC20 property. 29 | */ 30 | function detailedPrice() external virtual returns (Number memory); 31 | 32 | /** 33 | * @notice The total supply of the token. The value of Number.num here is the same as `totalSupply()` 34 | * @dev detailedTVL() / detailedTotalSupply() == detailedPrice() 35 | */ 36 | function detailedTotalSupply() external virtual returns (Number memory); 37 | } 38 | -------------------------------------------------------------------------------- /src/vaults/EthVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {Vault, MathUpgradeable, Math, SafeTransferLib, ERC20} from "src/vaults/Vault.sol"; 5 | import {IWETH} from "src/interfaces/IWETH.sol"; 6 | 7 | /// @notice The same as Vault, but ONLY raw ether can be withdrawn. 8 | contract EthVault is Vault { 9 | using SafeTransferLib for ERC20; 10 | 11 | /// @dev We need this to receive ETH when calling WETH.withdraw() 12 | receive() external payable {} 13 | 14 | function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares) 15 | internal 16 | virtual 17 | override 18 | { 19 | _liquidate(assets); 20 | 21 | // Slippage during liquidation means we might get less than `assets` amount of `_asset` 22 | assets = Math.min(_asset.balanceOf(address(this)), assets); 23 | uint256 assetsFee = _getWithdrawalFee(assets, owner); 24 | uint256 assetsToUser = assets - assetsFee; 25 | 26 | // Burn shares and give user equivalent value in `_asset` (minus withdrawal fees) 27 | if (caller != owner) _spendAllowance(owner, caller, shares); 28 | _burn(owner, shares); 29 | emit Withdraw(caller, receiver, owner, assets, shares); 30 | 31 | // Convert WETH to ETH and send to user 32 | IWETH(address(_asset)).withdraw(assetsToUser); 33 | (bool success,) = receiver.call{value: assetsToUser}(""); 34 | require(success, "EthVault: ETH transfer failed"); 35 | // Send withdrawal fee to governance 36 | _asset.safeTransfer(governance, assetsFee); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/vaults/EthVaultV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {VaultV2, MathUpgradeable, SafeTransferLib, ERC20} from "src/vaults/VaultV2.sol"; 5 | import {IWETH} from "src/interfaces/IWETH.sol"; 6 | 7 | /// @notice The same as Vault, but ONLY raw ether can be withdrawn. 8 | contract EthVaultV2 is VaultV2 { 9 | using SafeTransferLib for ERC20; 10 | 11 | /// @dev We need this to receive ETH when calling WETH.withdraw() 12 | receive() external payable {} 13 | 14 | function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares) 15 | internal 16 | virtual 17 | override 18 | { 19 | _liquidate(assets); 20 | 21 | // Slippage during liquidation means we might get less than `assets` amount of `_asset` 22 | assets = MathUpgradeable.min(_asset.balanceOf(address(this)), assets); 23 | uint256 assetsFee = _getWithdrawalFee(assets, owner); 24 | uint256 assetsToUser = assets - assetsFee; 25 | 26 | // Burn shares and give user equivalent value in `_asset` (minus withdrawal fees) 27 | if (caller != owner) _spendAllowance(owner, caller, shares); 28 | _burn(owner, shares); 29 | emit Withdraw(caller, receiver, owner, assets, shares); 30 | 31 | // Convert WETH to ETH and send to user 32 | IWETH(address(_asset)).withdraw(assetsToUser); 33 | (bool success,) = receiver.call{value: assetsToUser}(""); 34 | require(success, "EthVault: ETH transfer failed"); 35 | // Send withdrawal fee to governance 36 | _asset.safeTransfer(governance, assetsFee); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/vaults/HarvestStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC721} from "solmate/src/tokens/ERC721.sol"; 5 | import {AffineGovernable} from "src/utils/audited/AffineGovernable.sol"; 6 | 7 | abstract contract HarvestStorage is AffineGovernable { 8 | uint128 public performanceFeeBps; 9 | uint128 public accumulatedPerformanceFee; 10 | 11 | function setPerformanceFeeBps(uint128 _newFeeBps) external onlyGovernance { 12 | performanceFeeBps = _newFeeBps; 13 | } 14 | 15 | event PerformanceFeeWithdrawn(uint256 amount); 16 | } 17 | -------------------------------------------------------------------------------- /src/vaults/NftGate.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {ERC721} from "solmate/src/tokens/ERC721.sol"; 5 | import {AffineGovernable} from "src/utils/audited/AffineGovernable.sol"; 6 | 7 | abstract contract NftGate is AffineGovernable { 8 | ERC721 public accessNft; 9 | uint16 public withdrawalFeeWithNft; 10 | bool needNftToDeposit; 11 | bool nftDiscountActive; 12 | 13 | function setAccessNft(ERC721 _accessNft) external onlyGovernance { 14 | accessNft = _accessNft; 15 | } 16 | 17 | function setWithdrawalFeeWithNft(uint16 _newFee) external onlyGovernance { 18 | withdrawalFeeWithNft = _newFee; 19 | } 20 | 21 | function setNftProperties(bool _needNftToDeposit, bool _nftDiscountActive) external onlyGovernance { 22 | needNftToDeposit = _needNftToDeposit; 23 | nftDiscountActive = _nftDiscountActive; 24 | } 25 | 26 | function _checkNft(address owner) internal view { 27 | if (needNftToDeposit) require(accessNft.balanceOf(owner) > 0, "Caller has no access NFT"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/vaults/cross-chain-vault/DummyRelay.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /// @dev this is used in place of BaseRelayRecipient 5 | /// @dev helps to keep the proxy storage layout unchanged 6 | abstract contract DummyRelay { 7 | address private _trustedForwarder; 8 | 9 | function _setTrustedForwarder(address _forwarder) internal { 10 | _trustedForwarder = _forwarder; 11 | } 12 | 13 | function trustedForwarder() public view virtual returns (address) { 14 | return _trustedForwarder; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/vaults/cross-chain-vault/RebalanceStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {RebalanceModule} from "src/vaults/cross-chain-vault/RebalanceModule.sol"; 5 | import {AffineGovernable} from "src/utils/audited/AffineGovernable.sol"; 6 | 7 | abstract contract RebalanceStorage is AffineGovernable { 8 | RebalanceModule public rebalanceModule; 9 | 10 | function setRebalanceModule(address _rebalanceModule) external onlyGovernance { 11 | rebalanceModule = RebalanceModule(_rebalanceModule); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/vaults/cross-chain-vault/audited/Forwarder.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 33 Line 10 | * Extended: False 11 | * Changes: None 12 | */ 13 | import {MinimalForwarder} from "@openzeppelin/contracts/metatx/MinimalForwarder.sol"; 14 | import {uncheckedInc} from "src/libs/audited/Unchecked.sol"; 15 | 16 | contract Forwarder is MinimalForwarder { 17 | function executeBatch(ForwardRequest[] calldata requests, bytes calldata signatures) external payable { 18 | // get 65 byte chunks, each chunk is a signature 19 | uint256 start = 0; 20 | uint256 end = 65; 21 | 22 | for (uint256 i = 0; i < requests.length; i = uncheckedInc(i)) { 23 | ForwardRequest calldata req = requests[i]; 24 | bytes calldata sig = signatures[start:end]; 25 | start += 65; 26 | end += 65; 27 | (bool success,) = execute(req, sig); 28 | require(success, "Fwd: call failed"); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/vaults/cross-chain-vault/escrow/audited/BridgeEscrow.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 58 Line 10 | * Extended: No 11 | * Changes: None 12 | */ 13 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 14 | import {SafeTransferLib} from "solmate/src/utils/SafeTransferLib.sol"; 15 | 16 | import {BaseVault} from "src/vaults/cross-chain-vault/audited/BaseVault.sol"; 17 | 18 | abstract contract BridgeEscrow { 19 | using SafeTransferLib for ERC20; 20 | 21 | /// @notice The input asset. 22 | ERC20 public immutable asset; 23 | /// @notice The wormhole router contract. 24 | address public immutable wormholeRouter; 25 | /// @notice Governance address (shared with vault). 26 | address public immutable governance; 27 | 28 | /** 29 | * @notice Emitted whenever we transfer funds from this escrow to the vault 30 | * @param assets The amount of assets transferred 31 | */ 32 | event TransferToVault(uint256 assets); 33 | 34 | constructor(BaseVault _vault) { 35 | wormholeRouter = _vault.wormholeRouter(); 36 | asset = ERC20(_vault.asset()); 37 | governance = _vault.governance(); 38 | } 39 | 40 | /** 41 | * @notice Send assets to vault. 42 | * @param assets The amount of assets to send. 43 | * @param exitProof Proof needed by Polygon Pos bridge to unlock assets on Ethereum. 44 | */ 45 | function clearFunds(uint256 assets, bytes calldata exitProof) external { 46 | require(msg.sender == wormholeRouter, "BE: Only wormhole router"); 47 | _clear(assets, exitProof); 48 | } 49 | 50 | /// @notice Escape hatch for governance in an emergency. 51 | function rescueFunds(uint256 amount, bytes calldata exitProof) external { 52 | require(msg.sender == governance, "BE: Only Governance"); 53 | _clear(amount, exitProof); 54 | } 55 | 56 | function _clear(uint256 assets, bytes calldata exitProof) internal virtual; 57 | } 58 | -------------------------------------------------------------------------------- /src/vaults/cross-chain-vault/escrow/audited/L1BridgeEscrow.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 47 Line 10 | * Extended: False 11 | */ 12 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 13 | import {SafeTransferLib} from "solmate/src/utils/SafeTransferLib.sol"; 14 | 15 | import {IRootChainManager} from "src/interfaces/IRootChainManager.sol"; 16 | import {BridgeEscrow} from "./BridgeEscrow.sol"; 17 | import {L1Vault} from "src/vaults/cross-chain-vault/audited/L1Vault.sol"; 18 | 19 | contract L1BridgeEscrow is BridgeEscrow { 20 | using SafeTransferLib for ERC20; 21 | 22 | /// @notice The L1Vault. 23 | L1Vault public immutable vault; 24 | /// @notice Polygon Pos Bridge manager. See https://github.com/maticnetwork/pos-portal/blob/41d45f7eff5b298941a2547afa0073a6c36b2b9c/contracts/root/RootChainManager/RootChainManager.sol 25 | IRootChainManager public immutable rootChainManager; 26 | 27 | constructor(L1Vault _vault, IRootChainManager _manager) BridgeEscrow(_vault) { 28 | vault = _vault; 29 | rootChainManager = _manager; 30 | } 31 | 32 | function _clear(uint256 assets, bytes calldata exitProof) internal override { 33 | // Exit tokens, after this the withdrawn tokens from L2 will be reflected in the L1 BridgeEscrow 34 | // NOTE: This function can fail if the exitProof provided is fake or has already been processed 35 | // In either case, we want to send at least `assets` to the vault since we know that the L2Vault sent `assets` 36 | try rootChainManager.exit(exitProof) {} catch {} 37 | 38 | // Transfer exited tokens to L1 Vault. 39 | uint256 balance = asset.balanceOf(address(this)); 40 | require(balance >= assets, "BE: Funds not received"); 41 | asset.safeTransfer(address(vault), balance); 42 | 43 | emit TransferToVault(balance); 44 | vault.afterReceive(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/vaults/cross-chain-vault/escrow/audited/L2BridgeEscrow.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 48 Line 10 | * Extended: False 11 | * Changes: None 12 | */ 13 | import {ERC20} from "solmate/src/tokens/ERC20.sol"; 14 | import {SafeTransferLib} from "solmate/src/utils/SafeTransferLib.sol"; 15 | 16 | import {BridgeEscrow} from "./BridgeEscrow.sol"; 17 | import {L2Vault} from "src/vaults/cross-chain-vault/audited/L2Vault.sol"; 18 | 19 | interface IChildERC20 { 20 | function withdraw(uint256 amount) external; 21 | } 22 | 23 | contract L2BridgeEscrow is BridgeEscrow { 24 | using SafeTransferLib for ERC20; 25 | 26 | /// @notice The L2Vault. 27 | L2Vault public immutable vault; 28 | 29 | constructor(L2Vault _vault) BridgeEscrow(_vault) { 30 | vault = _vault; 31 | } 32 | 33 | /// @notice Send `amount` of `asset` to L1BridgeEscrow. 34 | function withdraw(uint256 amount) external { 35 | require(msg.sender == address(vault), "BE: Only vault"); 36 | IChildERC20(address(asset)).withdraw(amount); 37 | } 38 | 39 | function _clear(uint256 amount, bytes calldata /* exitProof */ ) internal override { 40 | uint256 balance = asset.balanceOf(address(this)); 41 | require(balance >= amount, "BE: Funds not received"); 42 | asset.safeTransfer(address(vault), balance); 43 | 44 | emit TransferToVault(balance); 45 | vault.afterReceive(balance); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/vaults/cross-chain-vault/router/audited/Router.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | /*////////////////////////////////////////////////////////////// 5 | AUDIT INFO 6 | //////////////////////////////////////////////////////////////*/ 7 | /** 8 | * Audits: 9 | * 1. Nov 8, 2022, size: 27 Line 10 | * Extended: False 11 | * Changes: Dropped Relayer 12 | */ 13 | import {ERC4626Router} from "./ERC4626Router.sol"; 14 | import {IWETH} from "src/interfaces/IWETH.sol"; 15 | 16 | contract Router is ERC4626Router { 17 | constructor(string memory name, IWETH _weth) ERC4626Router(name) { 18 | weth = _weth; 19 | } 20 | 21 | IWETH public immutable weth; 22 | 23 | function depositNative() external payable { 24 | weth.deposit{value: msg.value}(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/vaults/custom/DegenEthVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {EthVaultV2} from "src/vaults/EthVaultV2.sol"; 5 | 6 | contract DegenEthVault is EthVaultV2 {} 7 | -------------------------------------------------------------------------------- /src/vaults/custom/DegenVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {StrategyVault} from "src/vaults/locked/StrategyVault.sol"; 5 | 6 | contract DegenVault is StrategyVault { 7 | function _initialShareDecimals() internal pure override returns (uint8) { 8 | return 10; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/vaults/custom/DegenVaultV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.16; 3 | 4 | import {StrategyVaultV2} from "src/vaults/locked/StrategyVaultV2.sol"; 5 | 6 | contract DegenVaultV2 is StrategyVaultV2 { 7 | function _initialShareDecimals() internal pure override returns (uint8) { 8 | return 10; 9 | } 10 | } 11 | 12 | contract DegenVaultV2Eth is StrategyVaultV2 { 13 | function _initialShareDecimals() internal pure override returns (uint8) { 14 | return 10; 15 | } 16 | } 17 | 18 | contract HighYieldLpVaultEth is StrategyVaultV2 { 19 | function _initialShareDecimals() internal pure override returns (uint8) { 20 | return 10; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/vaults/custom/L2USDEarnVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {L2Vault} from "src/vaults/cross-chain-vault/audited/L2Vault.sol"; 5 | 6 | /** 7 | * deployment date: Dec 11,2023 8 | * vault: cross-chain usd earn in polygon 9 | */ 10 | contract L2USDEarnVault is L2Vault {} 11 | -------------------------------------------------------------------------------- /src/vaults/restaking/DelegatorBeacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; 5 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 6 | 7 | interface IDelegatorBeacon { 8 | function owner() external returns (address); 9 | } 10 | 11 | /** 12 | * @title DelegatorBeacon 13 | * @dev Delegator Beacon contract 14 | */ 15 | contract DelegatorBeacon is Ownable { 16 | UpgradeableBeacon immutable beacon; 17 | 18 | address public blueprint; 19 | 20 | /** 21 | * @dev Constructor 22 | * @param _initBlueprint Initial blueprint address 23 | * @param governance Governance address 24 | */ 25 | constructor(address _initBlueprint, address governance) { 26 | beacon = new UpgradeableBeacon(_initBlueprint); 27 | blueprint = _initBlueprint; 28 | transferOwnership(governance); 29 | } 30 | /** 31 | * @notice Update the blueprint 32 | * @param _newBlueprint New blueprint address 33 | */ 34 | 35 | function update(address _newBlueprint) public onlyOwner { 36 | beacon.upgradeTo(_newBlueprint); 37 | blueprint = _newBlueprint; 38 | } 39 | /** 40 | * @notice Get the implementation address 41 | * @return Implementation address 42 | */ 43 | 44 | function implementation() public view returns (address) { 45 | return beacon.implementation(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/vaults/restaking/DelegatorFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; 5 | 6 | import {UltraLRT} from "src/vaults/restaking/UltraLRT.sol"; 7 | import {EigenDelegator} from "src/vaults/restaking/EigenDelegator.sol"; 8 | 9 | interface IDelegatorFactory { 10 | function createDelegator(address _operator) external returns (address); 11 | function vault() external returns (address); 12 | } 13 | 14 | /** 15 | * @title DelegatorFactory 16 | * @dev Delegator Factory contract 17 | */ 18 | contract DelegatorFactory { 19 | address public vault; 20 | 21 | /** 22 | * @dev Modifier to allow function calls only from the vault 23 | */ 24 | modifier onlyVault() { 25 | require(msg.sender == vault, "DF: only vault"); 26 | _; 27 | } 28 | /** 29 | * @dev Constructor 30 | * @param _vault Vault address 31 | */ 32 | 33 | constructor(address _vault) { 34 | vault = _vault; 35 | } 36 | /** 37 | * @notice Create a new delegator 38 | * @param _operator Operator address 39 | * @return Delegator address 40 | */ 41 | 42 | function createDelegator(address _operator) external onlyVault returns (address) { 43 | BeaconProxy bProxy = new BeaconProxy( 44 | UltraLRT(vault).beacon(), abi.encodeWithSelector(EigenDelegator.initialize.selector, vault, _operator) 45 | ); 46 | return address(bProxy); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/vaults/restaking/IDelegator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | interface IDelegator { 5 | // vault request to withdraw assets 6 | function requestWithdrawal(uint256 assets) external; 7 | // vault will check the availability of liquid assets 8 | function checkAssetAvailability(uint256 assets) external view returns (bool); 9 | // vault withdraw liquid assets call by vault 10 | function delegate(uint256 amount) external; 11 | // vault delegate assets to delegator 12 | function withdraw() external; 13 | // get delegator tvl 14 | function totalLockedValue() external returns (uint256); 15 | 16 | function withdrawableAssets() external view returns (uint256); 17 | function queuedAssets() external view returns (uint256); 18 | } 19 | -------------------------------------------------------------------------------- /src/vaults/restaking/SymDelegatorFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity =0.8.16; 3 | 4 | import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; 5 | 6 | import {UltraLRT} from "src/vaults/restaking/UltraLRT.sol"; 7 | import {SymbioticDelegator} from "src/vaults/restaking/SymbioticDelegator.sol"; 8 | 9 | /** 10 | * @title SymDelegatorFactory 11 | * @dev SymDelegator Factory contract 12 | */ 13 | contract SymDelegatorFactory { 14 | address public vault; 15 | 16 | /** 17 | * @dev Modifier to allow function calls only from the vault 18 | */ 19 | modifier onlyVault() { 20 | require(msg.sender == vault, "SDF: only vault"); 21 | _; 22 | } 23 | 24 | /** 25 | * @dev Constructor 26 | * @param _vault Vault address 27 | */ 28 | constructor(address _vault) { 29 | vault = _vault; 30 | } 31 | 32 | /** 33 | * @notice Create a new delegator 34 | * @param _collateral Collateral address 35 | * @return proxy Delegator address 36 | */ 37 | function createDelegator(address _collateral) external onlyVault returns (address proxy) { 38 | proxy = address( 39 | new BeaconProxy( 40 | UltraLRT(vault).beacon(), 41 | abi.encodeWithSelector(SymbioticDelegator.initialize.selector, vault, _collateral) 42 | ) 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/vaults/restaking/affine ultraETH fundflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AffineLabs/contracts/8a830e44d666ecb9cee55b792d35ceeb522ab19d/src/vaults/restaking/affine ultraETH fundflow.png -------------------------------------------------------------------------------- /tasks/accounts.ts: -------------------------------------------------------------------------------- 1 | import { task } from "hardhat/config"; 2 | 3 | // This is a sample Hardhat task. To learn how to create your own go to 4 | // https://hardhat.org/guides/create-task.html 5 | task("accounts", "Prints the list of accounts", async (args, hre) => { 6 | const accounts = await hre.ethers.getSigners(); 7 | 8 | for (const account of accounts) { 9 | console.log(await account.getAddress()); 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /tasks/unblock.ts: -------------------------------------------------------------------------------- 1 | // Example run: npx hardhat --network eth-goerli unblock --nonce 408 --price 2 2 | import { task } from "hardhat/config"; 3 | import { ethers } from "ethers"; 4 | 5 | task("unblock", "Unblock tx") 6 | .addParam("nonce", "Nonce of the tx that we are trying to unblock") 7 | .addParam("price", "Gas price in Gwei") 8 | .setAction(async ({ nonce, price }, hre) => { 9 | const [deployer] = await hre.ethers.getSigners(); 10 | const tx = await deployer.sendTransaction({ 11 | to: deployer.address, 12 | nonce: parseInt(nonce), 13 | gasPrice: ethers.utils.parseUnits(price, "gwei"), 14 | }); 15 | console.log("Replacement Tx:\n", tx); 16 | await tx.wait(); 17 | }); 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "es5", 5 | "module": "commonjs", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "outDir": "dist", 9 | "resolveJsonModule": true, 10 | "skipLibCheck": true 11 | }, 12 | "include": ["./scripts", "./test", "./typechain"], 13 | "files": ["./hardhat.config.ts"] 14 | } 15 | --------------------------------------------------------------------------------