Skip to content

Commit

Permalink
Merge pull request #10 from cyberconnecthq/feat/cybervaultv3
Browse files Browse the repository at this point in the history
[FEATURE WIP] CyberVault V3
  • Loading branch information
HaoPeiwen authored Mar 26, 2024
2 parents 2dd552f + ba66886 commit 91b5ca6
Show file tree
Hide file tree
Showing 12 changed files with 700 additions and 6 deletions.
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

0 comments on commit 91b5ca6

Please sign in to comment.