Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
SoraSuegami committed Nov 12, 2023
2 parents 3d148b5 + 1871987 commit 0115a6d
Show file tree
Hide file tree
Showing 77 changed files with 117,791 additions and 110,492 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"scripts": {
"test": "yarn workspaces -pt run test",
"dev-setup": "yarn workspace @email-wallet/circom dev-setup",
"prettier": "prettier --write \"packages/contracts/**/*.{js,jsx,ts,tsx,json,sol}\""
"prettier": "prettier --write \"packages/contracts/**/*.{js,jsx,ts,tsx,sol}\""
},
"workspaces": [
"packages/*"
Expand Down
10 changes: 8 additions & 2 deletions packages/circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
"license": "MIT",
"version": "1.0.0",
"scripts": {
"build": "mkdir -p build && circom src/account_creation.circom --r1cs --wasm --sym -l ../../node_modules -o ./build && circom src/account_init.circom --r1cs --wasm --sym -l ../../node_modules -o ./build && circom src/account_transport.circom --r1cs --wasm --sym -l ../../node_modules -o ./build && circom src/claim.circom --r1cs --wasm --sym -l ../../node_modules -o ./build && circom src/email_sender.circom --r1cs --wasm --sym -l ../../node_modules -o ./build && circom src/announcement.circom --r1cs --wasm --sym -l ../../node_modules -o ./build",
"build": "mkdir -p build && yarn build-account-creation && yarn build-account-init && yarn build-account-transport && yarn build-claim && yarn build-email-sender",
"build-account-creation": "mkdir -p build/account_creation && circom src/account_creation.circom --r1cs --wasm --sym -l ../../node_modules -o ./build/account_creation",
"build-account-init": "mkdir -p build/account_init && circom src/account_init.circom --r1cs --wasm --sym -l ../../node_modules -o ./build/account_init",
"build-account-transport": "mkdir -p build/account_transport && circom src/account_transport.circom --r1cs --wasm --sym -l ../../node_modules -o ./build/account_transport",
"build-claim": "mkdir -p build/claim && circom src/claim.circom --r1cs --wasm --sym -l ../../node_modules -o ./build/claim",
"build-email-sender": "mkdir -p build/email_sender && circom src/email_sender.circom --r1cs --wasm --sym -l ../../node_modules -o ./build/email_sender",
"build-announcement": "mkdir -p build/announcement && circom src/announcement.circom --r1cs --wasm --sym -l ../../node_modules -o ./build/announcement",
"dev-setup": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/dev-setup.ts --output ./build",
"gen-account-creation-input": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/account_creation.ts",
"gen-account-init-input": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/account_init.ts",
Expand Down Expand Up @@ -52,4 +58,4 @@
]
]
}
}
}
2,677 changes: 1,638 additions & 1,039 deletions packages/contracts/artifacts/AccountCreationVerifier.sol/AccountCreationVerifier.json

Large diffs are not rendered by default.

4,491 changes: 2,346 additions & 2,145 deletions packages/contracts/artifacts/AccountHandler.sol/AccountHandler.json

Large diffs are not rendered by default.

8,331 changes: 4,266 additions & 4,065 deletions packages/contracts/artifacts/AccountHandler.t.sol/AccountTest.json

Large diffs are not rendered by default.

3,640 changes: 2,214 additions & 1,426 deletions packages/contracts/artifacts/AccountInitVerifier.sol/AccountInitVerifier.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

3,212 changes: 1,958 additions & 1,254 deletions packages/contracts/artifacts/AnnouncementVerifier.sol/AnnouncementVerifier.json

Large diffs are not rendered by default.

2,356 changes: 1,446 additions & 910 deletions packages/contracts/artifacts/ClaimVerifier.sol/ClaimVerifier.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

3,127 changes: 1,564 additions & 1,563 deletions packages/contracts/artifacts/DeployEmailWallet.s.sol/Deploy.json

Large diffs are not rendered by default.

383 changes: 192 additions & 191 deletions packages/contracts/artifacts/DeployTokenRegistry.s.sol/Deploy.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

5,566 changes: 3,366 additions & 2,200 deletions packages/contracts/artifacts/EmailSenderVerifier.sol/EmailSenderVerifier.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

6,334 changes: 3,179 additions & 3,155 deletions packages/contracts/artifacts/EmailWalletCore.cmd.send.t.sol/TransferTest.json

Large diffs are not rendered by default.

9,160 changes: 4,592 additions & 4,568 deletions packages/contracts/artifacts/EmailWalletCore.emailOp.t.sol/EmailOpValidationTest.json

Large diffs are not rendered by default.

10,321 changes: 5,213 additions & 5,108 deletions packages/contracts/artifacts/EmailWalletCore.sol/EmailWalletCore.json

Large diffs are not rendered by default.

15,401 changes: 7,843 additions & 7,558 deletions packages/contracts/artifacts/EmailWalletCore.uf.t.sol/UnclaimedFundTest.json

Large diffs are not rendered by default.

23,583 changes: 11,910 additions & 11,673 deletions packages/contracts/artifacts/EmailWalletCore.us.t.sol/UnclaimedStateTest.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

3,917 changes: 2,002 additions & 1,915 deletions packages/contracts/artifacts/ExtensionHandler.t.sol/ExtensionTest.json

Large diffs are not rendered by default.

26,100 changes: 13,224 additions & 12,876 deletions packages/contracts/artifacts/Integration.t.sol/IntegrationTest.json

Large diffs are not rendered by default.

12,788 changes: 6,406 additions & 6,382 deletions packages/contracts/artifacts/IntegrationTestHelper.sol/IntegrationTestHelper.json

Large diffs are not rendered by default.

2,539 changes: 1,273 additions & 1,266 deletions packages/contracts/artifacts/NFTExtension.sol/NFTExtension.json

Large diffs are not rendered by default.

411 changes: 206 additions & 205 deletions packages/contracts/artifacts/PoolFinder.sol/PoolFinder.json

Large diffs are not rendered by default.

2,062 changes: 1,094 additions & 968 deletions packages/contracts/artifacts/RelayerHandler.t.sol/RelayerTest.json

Large diffs are not rendered by default.

603 changes: 302 additions & 301 deletions packages/contracts/artifacts/SetChainOfTokenRegistry.s.sol/Deploy.json

Large diffs are not rendered by default.

753 changes: 377 additions & 376 deletions packages/contracts/artifacts/SetDKIMPublicKeyHash.s.sol/Update.json

Large diffs are not rendered by default.

597 changes: 299 additions & 298 deletions packages/contracts/artifacts/SetTokenOfNFTExtension.sol/Deploy.json

Large diffs are not rendered by default.

651 changes: 326 additions & 325 deletions packages/contracts/artifacts/SetTokenOfTokenRegistry.s.sol/Deploy.json

Large diffs are not rendered by default.

5,757 changes: 2,879 additions & 2,878 deletions packages/contracts/artifacts/SubjectUtils.sol/SubjectUtils.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2,343 changes: 1,184 additions & 1,159 deletions packages/contracts/artifacts/TokenRegistry.sol/TokenRegistry.json

Large diffs are not rendered by default.

8,451 changes: 4,536 additions & 3,915 deletions packages/contracts/artifacts/UnclaimsHandler.sol/UnclaimsHandler.json

Large diffs are not rendered by default.

3,601 changes: 1,803 additions & 1,798 deletions packages/contracts/artifacts/UniswapExtension.sol/UniswapExtension.json

Large diffs are not rendered by default.

6,113 changes: 3,057 additions & 3,056 deletions packages/contracts/artifacts/Verifier.sol/AllVerifiers.json

Large diffs are not rendered by default.

2,008 changes: 1,016 additions & 992 deletions packages/contracts/artifacts/Verifier.t.sol/VerifierTest.json

Large diffs are not rendered by default.

29 changes: 26 additions & 3 deletions packages/contracts/script/DeployEmailWallet.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,35 @@ contract Deploy is Script {
address(core),
tokenRegistry,
uniswapV3Router,
0x1F98431c8aD98523631AE4a59f267346ea31F984
0x1F98431c8aD98523631AE4a59f267346ea31F984
);
uniswapExtTemplates[0] = ["Swap", "{tokenAmount}", "to", "{string}"];
uniswapExtTemplates[1] = ["Swap", "{tokenAmount}", "to", "{string}", "with", "{amount}", "slippage"];
uniswapExtTemplates[2] = ["Swap", "{tokenAmount}", "to", "{string}", "under", "{uint}", "sqrt", "price", "limit"];
uniswapExtTemplates[3] = ["Swap", "{tokenAmount}", "to", "{string}", "with", "{amount}", "slippage", "under", "{uint}", "sqrt", "price", "limit"];
uniswapExtTemplates[2] = [
"Swap",
"{tokenAmount}",
"to",
"{string}",
"under",
"{uint}",
"sqrt",
"price",
"limit"
];
uniswapExtTemplates[3] = [
"Swap",
"{tokenAmount}",
"to",
"{string}",
"with",
"{amount}",
"slippage",
"under",
"{uint}",
"sqrt",
"price",
"limit"
];

defaultExtensions[1] = abi.encode("UniswapExtension", address(uniExt), uniswapExtTemplates, 0.001 ether); // TODO: Check max exec gas

Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/script/SetChainOfTokenRegistry.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contract Deploy is Script {
return;
}
address _tokenRegistry = vm.envAddress("TOKEN_REGISTRY");
if(_tokenRegistry == address(0)) {
if (_tokenRegistry == address(0)) {
console.log("TOKEN_REGISTRY env var not set");
return;
}
Expand Down
3 changes: 1 addition & 2 deletions packages/contracts/script/SetTokenOfNFTExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contract Deploy is Script {
return;
}
address _nftExtension = vm.envAddress("NFT_EXTENSION");
if(_nftExtension == address(0)) {
if (_nftExtension == address(0)) {
console.log("NFT_EXTENSION env var not set");
return;
}
Expand All @@ -23,6 +23,5 @@ contract Deploy is Script {
NFTExtension nftExtension = NFTExtension(_nftExtension);
nftExtension.setNFTAddress(tokenName, tokenAddr);
vm.stopBroadcast();

}
}
2 changes: 1 addition & 1 deletion packages/contracts/script/SetTokenOfTokenRegistry.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contract Deploy is Script {
return;
}
address _tokenRegistry = vm.envAddress("TOKEN_REGISTRY");
if(_tokenRegistry == address(0)) {
if (_tokenRegistry == address(0)) {
console.log("TOKEN_REGISTRY env var not set");
return;
}
Expand Down
17 changes: 14 additions & 3 deletions packages/contracts/src/EmailWalletCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,10 @@ contract EmailWalletCore {
}
// Return whatever ETH was sent in case unclaimed fund/state registration didnt happen
else {
require(currContext.registeredUnclaimId == 0, "registeredUnclaimId must be zero if no unclaimed fund/state is registered");
require(
currContext.registeredUnclaimId == 0,
"registeredUnclaimId must be zero if no unclaimed fund/state is registered"
);
payable(msg.sender).transfer(msg.value);
}

Expand All @@ -246,7 +249,7 @@ contract EmailWalletCore {

if (feeAmountInToken > 0) {
address feeToken = tokenRegistry.getTokenAddress(emailOp.feeTokenName);

(bool transferSuccess, bytes memory transferErr) = _transferERC20FromUserWallet(
currContext.walletAddr,
msg.sender,
Expand All @@ -265,7 +268,15 @@ contract EmailWalletCore {
currContext.registeredUnclaimId = 0;
delete currContext.tokenAllowances;

emit EmailWalletEvents.EmailOpHandled(success, registeredUnclaimId, emailOp.emailNullifier, emailOp.emailAddrPointer, emailOp.recipientEmailAddrCommit, emailOp.recipientETHAddr, err);
emit EmailWalletEvents.EmailOpHandled(
success,
registeredUnclaimId,
emailOp.emailNullifier,
emailOp.emailAddrPointer,
emailOp.recipientEmailAddrCommit,
emailOp.recipientETHAddr,
err
);
}

/// For extension in context to register Unclaimed State during handleEmailOp
Expand Down
27 changes: 17 additions & 10 deletions packages/contracts/src/extensions/PoolFinder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,25 @@ contract PoolFinder {
factory = _factory;
}

function getPoolSlot0(address tokenA, address tokenB, uint24 fee) external view returns (
uint160 sqrtPriceX96,
int24 tick,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext,
uint8 feeProtocol,
bool unlocked
) {
function getPoolSlot0(
address tokenA,
address tokenB,
uint24 fee
)
external
view
returns (
uint160 sqrtPriceX96,
int24 tick,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext,
uint8 feeProtocol,
bool unlocked
)
{
address poolAddress = factory.getPool(tokenA, tokenB, fee);
require(poolAddress != address(0), "Pool not found");
return IUniswapV3Pool(poolAddress).slot0();
}

}
35 changes: 20 additions & 15 deletions packages/contracts/src/extensions/UniswapExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,20 @@ contract UniswapExtension is Extension {
templates[0] = ["Swap", "{tokenAmount}", "to", "{string}"];
templates[1] = ["Swap", "{tokenAmount}", "to", "{string}", "with", "{amount}", "slippage"];
templates[2] = ["Swap", "{tokenAmount}", "to", "{string}", "under", "{uint}", "sqrt", "price", "limit"];
templates[3] = ["Swap", "{tokenAmount}", "to", "{string}", "with", "{amount}", "slippage", "under", "{uint}", "sqrt", "price", "limit"];
templates[3] = [
"Swap",
"{tokenAmount}",
"to",
"{string}",
"with",
"{amount}",
"slippage",
"under",
"{uint}",
"sqrt",
"price",
"limit"
];
poolFinder = new PoolFinder(IUniswapV3Factory(_factory));
}

Expand Down Expand Up @@ -74,12 +87,12 @@ contract UniswapExtension is Extension {
slippagePoints = defaultSlippagePoints;

sqrtPriceLimitX96 = 0;
}
}

if (templateIndex == 1) {
uint256 slippagePoints256 = abi.decode(subjectParams[2], (uint256));
// This value is user input * 10^18, we need to revert it as (user input * 10^2).
slippagePoints256 = slippagePoints256 / 10**16;
slippagePoints256 = slippagePoints256 / 10 ** 16;
require(slippagePoints256 <= type(uint24).max, "slippagePoints256 argument overflow detected");
slippagePoints = uint24(slippagePoints256);

Expand All @@ -98,7 +111,7 @@ contract UniswapExtension is Extension {
if (templateIndex == 3) {
uint256 slippagePoints256 = abi.decode(subjectParams[2], (uint256));
// This value is user input * 10^18, we need to revert it as (user input * 10^2).
slippagePoints256 = slippagePoints256 / 10**16;
slippagePoints256 = slippagePoints256 / 10 ** 16;
require(slippagePoints256 <= type(uint24).max, "slippagePoints256 argument overflow detected");
slippagePoints = uint24(slippagePoints256);

Expand Down Expand Up @@ -146,11 +159,7 @@ contract UniswapExtension is Extension {
deadline: block.timestamp,
amountIn: wethAmount,
amountOutMinimum: 0,
sqrtPriceLimitX96: getSqrtPriceLimitX96(
wethAddr,
tokenOutAddr,
slippagePoints,
sqrtPriceLimitX96)
sqrtPriceLimitX96: getSqrtPriceLimitX96(wethAddr, tokenOutAddr, slippagePoints, sqrtPriceLimitX96)
});
router.exactInputSingle(swapParams2);
} else {
Expand All @@ -162,11 +171,7 @@ contract UniswapExtension is Extension {
deadline: block.timestamp,
amountIn: tokenInAmount,
amountOutMinimum: 0,
sqrtPriceLimitX96: getSqrtPriceLimitX96(
tokenInAddr,
tokenOutAddr,
slippagePoints,
sqrtPriceLimitX96)
sqrtPriceLimitX96: getSqrtPriceLimitX96(tokenInAddr, tokenOutAddr, slippagePoints, sqrtPriceLimitX96)
});
router.exactInputSingle(swapParams);
}
Expand All @@ -189,7 +194,7 @@ contract UniswapExtension is Extension {
bool zeroForOne = tokenIn < tokenOut;

(uint160 sqrtPriceX96, , , , , , ) = poolFinder.getPoolSlot0(tokenIn, tokenOut, poolFee);

if (sqrtPriceLimitX96 == 0) {
sqrtPriceLimitX96 = sqrtPriceX96;
}
Expand Down
1 change: 1 addition & 0 deletions packages/contracts/src/handlers/AccountHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ contract AccountHandler is Ownable {
/// @param emailAddrPointer hash(relayerRand, emailAddr)
/// @param emailDomain domain name of the sender's email
/// @param emailNullifier nullifier of the email used for proof generation
/// @param dkimPublicKeyHash DKIM public key hash of the email domain used in the proof generation
/// @param proof ZK proof as required by the verifier
function initializeAccount(
bytes32 emailAddrPointer,
Expand Down
48 changes: 30 additions & 18 deletions packages/contracts/src/handlers/UnclaimsHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,17 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
});

unclaimedFundOfId[fund.id] = fund;
numUnclaimedFunds ++;
emit EmailWalletEvents.UnclaimedFundRegistered(fund.id, emailAddrCommit, tokenAddr, amount, sender, expiryTime, 0, "");
numUnclaimedFunds++;
emit EmailWalletEvents.UnclaimedFundRegistered(
fund.id,
emailAddrCommit,
tokenAddr,
amount,
sender,
expiryTime,
0,
""
);
return fund.id;
}

Expand Down Expand Up @@ -146,7 +155,7 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
});

unclaimedFundOfId[fund.id] = fund;
numUnclaimedFunds ++;
numUnclaimedFunds++;
emit EmailWalletEvents.UnclaimedFundRegistered(
fund.id,
emailAddrCommit,
Expand Down Expand Up @@ -200,7 +209,7 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
),
"invalid proof"
);

address recipientAddr = accountHandler.getWalletOfSalt(
accountHandler.getInfoOfAccountKeyCommit(accountKeyCommit).walletSalt
);
Expand All @@ -213,7 +222,13 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
// Transfer claim fee to the sender (relayer)
payable(msg.sender).transfer(unclaimedFundClaimGas * maxFeePerGas);

emit EmailWalletEvents.UnclaimedFundClaimed(id, fund.emailAddrCommit, fund.tokenAddr, fund.amount, recipientAddr);
emit EmailWalletEvents.UnclaimedFundClaimed(
id,
fund.emailAddrCommit,
fund.tokenAddr,
fund.amount,
recipientAddr
);
}

/// @notice Return unclaimed fund after expiry time
Expand Down Expand Up @@ -258,7 +273,7 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
uint256 expiryTime,
uint256 announceCommitRandomness,
string calldata announceEmailAddr
) public payable returns (uint256){
) public payable returns (uint256) {
if (expiryTime == 0) {
expiryTime = block.timestamp + unclaimsExpiryDuration;
}
Expand All @@ -283,8 +298,8 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
Extension extension = Extension(extensionAddr);

unclaimedStateOfId[us.id] = us;
numUnclaimedStates ++;
numUnclaimedStates++;

try extension.registerUnclaimedState(us, false) {} catch Error(string memory reason) {
revert(string.concat("unclaimed state reg err: ", reason));
} catch {
Expand Down Expand Up @@ -318,10 +333,7 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
bytes calldata state,
bool isInternal
) public onlyOwner returns (uint256) {
require(
unclaimedStateOfId[numUnclaimedStates].sender == address(0),
"unclaimed state exists"
);
require(unclaimedStateOfId[numUnclaimedStates].sender == address(0), "unclaimed state exists");
require(state.length > 0, "state cannot be empty");

uint256 expiryTime = block.timestamp + unclaimsExpiryDuration;
Expand All @@ -338,7 +350,7 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
Extension extension = Extension(extensionAddr);

unclaimedStateOfId[us.id] = us;
numUnclaimedStates ++;
numUnclaimedStates++;

try extension.registerUnclaimedState(us, isInternal) {} catch Error(string memory reason) {
revert(string.concat("unclaimed state reg err: ", reason));
Expand Down Expand Up @@ -410,7 +422,8 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {

// Deducated consumed gas + 21k for eth transer from `unclaimedStateClaimGas` + gas to store one value and pass to extension
uint256 gasForExt = unclaimedStateClaimGas - (initialGas - gasleft()) - ETH_TRANSFER_GAS;
require(gasleft() > gasForExt, "insufficient gas left");
require(gasleft() * 63 > gasForExt * 64, "insufficient gas left");

// Relayer should get claim fee (gas reimbursement) even if extension call fails
// Simulation wont work, as extension logic will depend on global variables
try extension.claimUnclaimedState{gas: gasForExt}(us, recipientAddr) {
Expand All @@ -430,9 +443,7 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {

/// @notice Return unclaimed state after expiry time
/// @param id The id of the unclaimed state to claim.
function voidUnclaimedState(
uint256 id
) public nonReentrant returns (bool success, bytes memory returnData) {
function voidUnclaimedState(uint256 id) public nonReentrant returns (bool success, bytes memory returnData) {
uint256 initialGas = gasleft();
require(id < numUnclaimedStates, "invalid id");

Expand All @@ -448,7 +459,8 @@ contract UnclaimsHandler is ReentrancyGuard, Ownable {
// Gas consumed for verification and next steps is deducated from `unclaimedStateClaimGas`
// and rest is passed to extension
uint256 gasForExt = unclaimedStateClaimGas - (initialGas - gasleft()) - ETH_TRANSFER_GAS - WETH_DEPOSIT_GAS;
require(gasleft() > gasForExt, "insufficient gas left");
require(gasleft() * 63 > gasForExt * 64, "insufficient gas left");

// Callee should get gas reimbursement even if extension call fails
// Simulation wont work, as extension logic can depend on global variables
try extension.voidUnclaimedState{gas: gasForExt}(us) {
Expand Down
Loading

0 comments on commit 0115a6d

Please sign in to comment.