Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE WIP] CyberVault V3 #10

Merged
merged 9 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
url = https://github.com/eth-infinitism/account-abstraction
[submodule "lib/kernel"]
path = lib/kernel
url = https://github.com/zerodevapp/kernel
url = https://github.com/zerodevapp/kernel
1 change: 1 addition & 0 deletions docs/abi/CyberVaultV3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"DEFAULT_ADMIN_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"_tokenInWhitelist","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"_tokenOut","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"_uniswap","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IUniversalRouter"}],"stateMutability":"view"},{"type":"function","name":"_wrappedNativeCurrency","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"balance","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"balances","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"balancesByCurrency","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"depositPreApprove","inputs":[{"name":"depositTo","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositWithPermit","inputs":[{"name":"depositTo","type":"address","internalType":"address"},{"name":"_permit","type":"tuple","internalType":"struct ERC20PermitData","components":[{"name":"currency","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"erc20balances","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getRoleAdmin","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"grantRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"hasRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"migrateBalance","inputs":[{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"migrateERC20Balance","inputs":[{"name":"currency","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"proxiableUUID","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"receipient","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"renounceRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokeRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setV3Variables","inputs":[{"name":"uniswap","type":"address","internalType":"address"},{"name":"wrappedNativeCurrency","type":"address","internalType":"address"},{"name":"tokenOut","type":"address","internalType":"address"},{"name":"tokenInList","type":"address[]","internalType":"address[]"},{"name":"tokenInApproved","type":"bool[]","internalType":"bool[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"swapERC20PreApproveAndDeposit","inputs":[{"name":"depositTo","type":"address","internalType":"address"},{"name":"_intent","type":"tuple","internalType":"struct SwapIntent","components":[{"name":"tokenIn","type":"address","internalType":"address"},{"name":"tokenOut","type":"address","internalType":"address"},{"name":"tokenInAmount","type":"uint256","internalType":"uint256"},{"name":"tokenOutAmount","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address payable"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"poolFeesTier","type":"uint24","internalType":"uint24"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"swapERC20WithPermitAndDeposit","inputs":[{"name":"depositTo","type":"address","internalType":"address"},{"name":"_intent","type":"tuple","internalType":"struct SwapIntent","components":[{"name":"tokenIn","type":"address","internalType":"address"},{"name":"tokenOut","type":"address","internalType":"address"},{"name":"tokenInAmount","type":"uint256","internalType":"uint256"},{"name":"tokenOutAmount","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address payable"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"poolFeesTier","type":"uint24","internalType":"uint24"}]},{"name":"_permit","type":"tuple","internalType":"struct ERC20PermitData","components":[{"name":"currency","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"swapNativeAndDeposit","inputs":[{"name":"depositTo","type":"address","internalType":"address"},{"name":"_intent","type":"tuple","internalType":"struct SwapIntent","components":[{"name":"tokenIn","type":"address","internalType":"address"},{"name":"tokenOut","type":"address","internalType":"address"},{"name":"tokenInAmount","type":"uint256","internalType":"uint256"},{"name":"tokenOutAmount","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address payable"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"poolFeesTier","type":"uint24","internalType":"uint24"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"upgradeTo","inputs":[{"name":"newImplementation","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"upgradeToAndCall","inputs":[{"name":"newImplementation","type":"address","internalType":"address"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"withdraw","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"withdrawERC20","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"currency","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"AdminChanged","inputs":[{"name":"previousAdmin","type":"address","indexed":false,"internalType":"address"},{"name":"newAdmin","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"BeaconUpgraded","inputs":[{"name":"beacon","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Deposit","inputs":[{"name":"to","type":"address","indexed":false,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"DepositERC20","inputs":[{"name":"to","type":"address","indexed":false,"internalType":"address"},{"name":"currency","type":"address","indexed":false,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"previousAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"newAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"name":"implementation","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Withdraw","inputs":[{"name":"to","type":"address","indexed":false,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"WithdrawERC20","inputs":[{"name":"to","type":"address","indexed":false,"internalType":"address"},{"name":"currency","type":"address","indexed":false,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"InvalidPermitSignature","inputs":[]},{"type":"error","name":"SwapFailedBytes","inputs":[{"name":"reason","type":"bytes","internalType":"bytes"}]},{"type":"error","name":"SwapFailedString","inputs":[{"name":"reason","type":"string","internalType":"string"}]}]
1 change: 1 addition & 0 deletions docs/deploy/op-10/contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
| CyberVaultV2(Impl) | 0x041300287e6760196d798be6ce9bd3b485028950 |
| Timelock(V2) | 0x640dc26699c95a085086650a18028ab3f1454c81 |
| LaunchTokenPool | 0x454ba74c599340b1d868c693ccdb1a55feb8965d |
| CyberVaultV3(Impl) | 0xbf63825b8706ab8999940bf82d660cd9815a89f4 |
1 change: 1 addition & 0 deletions docs/deploy/op_sepolia-11155420/contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
| CyberPaymaster | 0x672cf56a66b6f6a0a97f188abe57249fb7eef909 |
| LaunchTokenPool | 0xd30e1c72742803de428799c34729168fe70534b2 |
| CyberVaultV2(Impl) | 0x251f21e67bd5dcfcf7278fcc5540cd406a2ccc8f |
| CyberVaultV3(Impl) | 0xbf63825b8706ab8999940bf82d660cd9815a89f4 |
25 changes: 25 additions & 0 deletions lib/uniswap/contracts/interfaces/IUniversalRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.14;

import {IERC721Receiver} from 'openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol';
import {IERC1155Receiver} from 'openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol';

interface IUniversalRouter is IERC721Receiver, IERC1155Receiver {
/// @notice Thrown when a required command has failed
error ExecutionFailed(uint256 commandIndex, bytes message);

/// @notice Thrown when attempting to send ETH directly to the contract
error ETHNotAccepted();

/// @notice Thrown when executing commands with an expired deadline
error TransactionDeadlinePassed();

/// @notice Thrown when attempting to execute commands and an incorrect number of inputs are provided
error LengthMismatch();

/// @notice Executes encoded commands along with provided inputs. Reverts if deadline has expired.
/// @param commands A set of concatenated commands, each 1 byte in length
/// @param inputs An array of byte strings containing abi encoded inputs for each command
/// @param deadline The deadline by which the transaction must be executed
function execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline) external payable;
}
74 changes: 74 additions & 0 deletions lib/uniswap/contracts/libraries/Commands.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.14;

/// @title Commands
/// @notice Command Flags used to decode commands
library Commands {
// Masks to extract certain bits of commands
bytes1 internal constant FLAG_ALLOW_REVERT = 0x80;
bytes1 internal constant COMMAND_TYPE_MASK = 0x3f;

// Command Types. Maximum supported command at this moment is 0x3f.

// Command Types where value<0x08, executed in the first nested-if block
uint256 constant V3_SWAP_EXACT_IN = 0x00;
uint256 constant V3_SWAP_EXACT_OUT = 0x01;
uint256 constant PERMIT2_TRANSFER_FROM = 0x02;
uint256 constant PERMIT2_PERMIT_BATCH = 0x03;
uint256 constant SWEEP = 0x04;
uint256 constant TRANSFER = 0x05;
uint256 constant PAY_PORTION = 0x06;
// COMMAND_PLACEHOLDER = 0x07;

// The commands are executed in nested if blocks to minimise gas consumption
// The following constant defines one of the boundaries where the if blocks split commands
uint256 constant FIRST_IF_BOUNDARY = 0x08;

// Command Types where 0x08<=value<=0x0f, executed in the second nested-if block
uint256 constant V2_SWAP_EXACT_IN = 0x08;
uint256 constant V2_SWAP_EXACT_OUT = 0x09;
uint256 constant PERMIT2_PERMIT = 0x0a;
uint256 constant WRAP_ETH = 0x0b;
uint256 constant UNWRAP_WETH = 0x0c;
uint256 constant PERMIT2_TRANSFER_FROM_BATCH = 0x0d;
uint256 constant BALANCE_CHECK_ERC20 = 0x0e;
// COMMAND_PLACEHOLDER = 0x0f;

// The commands are executed in nested if blocks to minimise gas consumption
// The following constant defines one of the boundaries where the if blocks split commands
uint256 constant SECOND_IF_BOUNDARY = 0x10;

// Command Types where 0x10<=value<0x18, executed in the third nested-if block
uint256 constant SEAPORT_V1_5 = 0x10;
uint256 constant LOOKS_RARE_V2 = 0x11;
uint256 constant NFTX = 0x12;
uint256 constant CRYPTOPUNKS = 0x13;
// 0x14;
uint256 constant OWNER_CHECK_721 = 0x15;
uint256 constant OWNER_CHECK_1155 = 0x16;
uint256 constant SWEEP_ERC721 = 0x17;

// The commands are executed in nested if blocks to minimise gas consumption
// The following constant defines one of the boundaries where the if blocks split commands
uint256 constant THIRD_IF_BOUNDARY = 0x18;

// Command Types where 0x18<=value<=0x1f, executed in the final nested-if block
uint256 constant X2Y2_721 = 0x18;
uint256 constant SUDOSWAP = 0x19;
uint256 constant NFT20 = 0x1a;
uint256 constant X2Y2_1155 = 0x1b;
uint256 constant FOUNDATION = 0x1c;
uint256 constant SWEEP_ERC1155 = 0x1d;
uint256 constant ELEMENT_MARKET = 0x1e;
// COMMAND_PLACEHOLDER = 0x1f;

// The commands are executed in nested if blocks to minimise gas consumption
// The following constant defines one of the boundaries where the if blocks split commands
uint256 constant FOURTH_IF_BOUNDARY = 0x20;

// Command Types where 0x20<=value
uint256 constant SEAPORT_V1_4 = 0x20;
uint256 constant EXECUTE_SUB_PLAN = 0x21;
uint256 constant APPROVE_ERC20 = 0x22;
// COMMAND_PLACEHOLDER for 0x23 to 0x3f (all unused)
}
38 changes: 38 additions & 0 deletions lib/uniswap/contracts/libraries/Constants.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.14;

/// @title Constant state
/// @notice Constant state used by the Universal Router
library Constants {
/// @dev Used for identifying cases when this contract's balance of a token is to be used as an input
/// This value is equivalent to 1<<255, i.e. a singular 1 in the most significant bit.
uint256 internal constant CONTRACT_BALANCE = 0x8000000000000000000000000000000000000000000000000000000000000000;

/// @dev Used for identifying cases when a v2 pair has already received input tokens
uint256 internal constant ALREADY_PAID = 0;

/// @dev Used as a flag for identifying the transfer of ETH instead of a token
address internal constant ETH = address(0);

/// @dev Used as a flag for identifying that msg.sender should be used, saves gas by sending more 0 bytes
address internal constant MSG_SENDER = address(1);

/// @dev Used as a flag for identifying address(this) should be used, saves gas by sending more 0 bytes
address internal constant ADDRESS_THIS = address(2);

/// @dev The length of the bytes encoded address
uint256 internal constant ADDR_SIZE = 20;

/// @dev The length of the bytes encoded fee
uint256 internal constant V3_FEE_SIZE = 3;

/// @dev The offset of a single token address (20) and pool fee (3)
uint256 internal constant NEXT_V3_POOL_OFFSET = ADDR_SIZE + V3_FEE_SIZE;

/// @dev The offset of an encoded pool key
/// Token (20) + Fee (3) + Token (20) = 43
uint256 internal constant V3_POP_OFFSET = NEXT_V3_POOL_OFFSET + ADDR_SIZE;

/// @dev The minimum length of an encoding that contains 2 or more pools
uint256 internal constant MULTIPLE_V3_POOLS_MIN_LENGTH = V3_POP_OFFSET + NEXT_V3_POOL_OFFSET;
}
1 change: 1 addition & 0 deletions misc/gen_abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const writeAbi = async () => {
"TokenReceiver.sol/TokenReceiver.json",
"CyberVault.sol/CyberVault.json",
"CyberVaultV2.sol/CyberVaultV2.json",
"CyberVaultV3.sol/CyberVaultV3.json",
"ECDSAValidator.sol/ECDSAValidator.json",
"LaunchTokenPool.sol/LaunchTokenPool.json",
];
Expand Down
3 changes: 2 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ forge-std/=lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/
solmate/=lib/solmate/
kernel/=lib/kernel/
account-abstraction/=lib/account-abstraction/contracts/
account-abstraction/=lib/account-abstraction/contracts/
universal-router/=lib/uniswap/
Loading
Loading