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

Gasless flow Permit2Proxy (v1.0.0) [Permit2Proxy v1.0.0] #782

Merged
merged 84 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
e4c5947
Add Permit2Proxy
ezynda3 Aug 22, 2024
797e772
Add Permit2Proxy
ezynda3 Aug 22, 2024
48b9703
forge install: Permit2
ezynda3 Aug 22, 2024
9795b16
Get basic test working...
ezynda3 Aug 23, 2024
745c5c7
Add more basic tests
ezynda3 Aug 26, 2024
e186436
Remove superfluous receiver param
ezynda3 Aug 26, 2024
143d4c2
Add utility method for getting a valid and working msgHash to sign
ezynda3 Aug 26, 2024
779bd8b
Change name to be more specific
ezynda3 Aug 26, 2024
f36a67e
Add Permit "v1" functionality
ezynda3 Aug 26, 2024
48de477
Add Permit "v1" tests
ezynda3 Aug 26, 2024
d119ca9
Add missing comments
ezynda3 Aug 26, 2024
484c918
Flesh out demo script
ezynda3 Aug 26, 2024
f582cbc
Finish demo script
ezynda3 Aug 27, 2024
9785369
Cleanup and comments
ezynda3 Aug 27, 2024
4cd03e0
Fix log
ezynda3 Aug 27, 2024
f18dab6
Remove extra files
ezynda3 Aug 27, 2024
0eaa7c8
Remove extra remapping
ezynda3 Aug 27, 2024
a3e6f5d
Remove unneeded lib
ezynda3 Aug 27, 2024
cfd1977
Add official Permit2 addresses
ezynda3 Aug 27, 2024
db2f0ff
Merge branch 'main' into gasless-revisited
ezynda3 Aug 28, 2024
e7395b2
Allow only signer to call using EIP2612
ezynda3 Aug 29, 2024
8364ac7
Merge branch 'gasless-revisited' of github.com:lifinance/contracts in…
ezynda3 Aug 29, 2024
5d772b0
Bind Permit2Proxy to a single diamond
ezynda3 Aug 29, 2024
2f8e953
Update deploy script
ezynda3 Aug 29, 2024
3d39c31
Implement non-gasless Permit2 flow
ezynda3 Aug 29, 2024
af38e51
Redeploy to staging and update demo script
ezynda3 Aug 29, 2024
056a8c2
Update comments and remove unneeded events/errors
ezynda3 Aug 30, 2024
1755f86
Add utility methods for determining the next valid nonce
ezynda3 Aug 30, 2024
17e5da3
Redeploy and update demo script
ezynda3 Aug 30, 2024
476ba04
Add documentation
ezynda3 Aug 30, 2024
10b6204
Fixes
ezynda3 Sep 2, 2024
f5f566d
Change witness type to be consistent with the rest of the codebase
ezynda3 Sep 3, 2024
be50801
Remove unneeded whitelist
ezynda3 Sep 3, 2024
671c048
Fixes
ezynda3 Sep 4, 2024
54ece21
Fixes
ezynda3 Sep 4, 2024
f277666
Boost test coverage
ezynda3 Sep 4, 2024
e40f49a
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Sep 6, 2024
010c923
More fixes
ezynda3 Sep 6, 2024
4397f59
More fixes
ezynda3 Sep 6, 2024
0e3debb
Merge branch 'main' into gasless-revisited
0xDEnYO Sep 9, 2024
5e64b4c
Merge branch 'gasless-revisited' of github.com:lifinance/contracts in…
0xDEnYO Sep 9, 2024
a9cb08a
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Sep 19, 2024
3eaf8ba
removes unused imports (audit issue#2)
0xDEnYO Sep 19, 2024
2ad55fa
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Sep 26, 2024
c3ad6f5
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Sep 30, 2024
976966d
adds WithdrawablePeriphery base contract to token withdrawals
0xDEnYO Sep 30, 2024
4a6e336
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Oct 7, 2024
b1ebb1c
audit report added
0xDEnYO Oct 7, 2024
59a356c
Update src/Periphery/Permit2Proxy.sol
0xDEnYO Oct 7, 2024
a40f709
Update src/Periphery/Permit2Proxy.sol
0xDEnYO Oct 7, 2024
9772ba1
rename test file to match naming convention
0xDEnYO Oct 10, 2024
b03e658
adds WithdrawablePeriphery base contract for token withdrawals
0xDEnYO Oct 10, 2024
bcf24aa
fix test
0xDEnYO Oct 10, 2024
40bf7ee
adds version tag to contract
0xDEnYO Oct 10, 2024
233a703
Merge branch 'withdrawable-periphery' into gasless-revisited
0xDEnYO Oct 10, 2024
552a080
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Oct 13, 2024
6200a1b
target state updated
0xDEnYO Oct 13, 2024
d95e58f
deploy script fixed
0xDEnYO Oct 13, 2024
959e1c9
deployed to PROD (arb, opt, pol)
0xDEnYO Oct 13, 2024
0565895
fix test
0xDEnYO Oct 14, 2024
6ab55d4
Update Witness Type Hash to match convention
ezynda3 Oct 15, 2024
2d8537e
Deploy update to staging
ezynda3 Oct 16, 2024
7c2ab14
update audit report (incl fixed typehash issue)
0xDEnYO Oct 18, 2024
369e8a2
Fix stype string as well
ezynda3 Oct 21, 2024
2da847b
Redeploy to staging
ezynda3 Oct 21, 2024
426807e
Update Permit2Proxy.t.sol
ezynda3 Nov 1, 2024
6b9c642
add demo for permit2 flow without witness
maxklenk Nov 4, 2024
b0b4bda
clean permit2 generation
maxklenk Nov 4, 2024
181566e
simplify signature generation
maxklenk Nov 9, 2024
8b6f059
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Nov 25, 2024
6113466
remove old openzeppelin lib
0xDEnYO Nov 25, 2024
f07b9a1
forge install: openzeppelin-contracts
0xDEnYO Nov 25, 2024
39aee6b
update audit log and report
0xDEnYO Nov 25, 2024
47c77d2
target state updated
0xDEnYO Nov 25, 2024
9c6f37b
deployed to various PROD networks (excl zksync)
0xDEnYO Nov 25, 2024
4e02a15
verified Permit2Proxy on base
0xDEnYO Nov 25, 2024
3794dbe
deploy to zksync
ezynda3 Nov 25, 2024
30e9704
diamond logs updated
0xDEnYO Nov 25, 2024
ec97ef2
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Nov 26, 2024
78a702b
bugfix in fixAuditLabel action
0xDEnYO Nov 26, 2024
c803f2d
fix logs
ezynda3 Nov 26, 2024
4bdfa05
fix test
ezynda3 Nov 26, 2024
1cf74ca
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Nov 28, 2024
ddfb557
Merge branch 'gasless-revisited' of github.com:lifinance/contracts in…
0xDEnYO Nov 28, 2024
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/Vectorized/solady
[submodule "lib/Permit2"]
path = lib/Permit2
url = https://github.com/Uniswap/Permit2
4 changes: 4 additions & 0 deletions config/permit2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"mainnet": "0x000000000022D473030F116dDEE9F6B43aC78BA3",
"arbitrum": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
}
28 changes: 17 additions & 11 deletions deployments/_deployments_log_file.json
Original file line number Diff line number Diff line change
Expand Up @@ -21793,16 +21793,6 @@
"VERIFIED": "true"
}
],
"1.0.1": [
{
"ADDRESS": "0x6e378C84e657C57b2a8d183CFf30ee5CC8989b61",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-08-14 18:28:47",
"CONSTRUCTOR_ARGS": "0x0000000000000000000000006ce9bf8cdab780416ad1fd87b318a077d2f50eac",
"SALT": "",
"VERIFIED": "true"
}
],
"1.0.1": [
{
"ADDRESS": "0x6e378C84e657C57b2a8d183CFf30ee5CC8989b61",
Expand Down Expand Up @@ -22407,5 +22397,21 @@
]
}
}
},
"Permit2Proxy": {
"arbitrum": {
"staging": {
"1.0.0": [
{
"ADDRESS": "0x442BBFD6a4641B2b710DFfa4754081eC7502a3F7",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-08-26 18:34:52",
"CONSTRUCTOR_ARGS": "0x00000000000000000000000011f1022ca6adef6400e5677528a80d49a069c00c000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3",
"SALT": "09072024",
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
"VERIFIED": "true"
}
]
}
}
}
}
}
3 changes: 2 additions & 1 deletion deployments/arbitrum.staging.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@
"CircleBridgeFacet": "0xa73a8BC8d36472269138c3233e24D0Ee0c344bd8",
"HopFacetOptimized": "0xf82135385765f1324257ffF74489F16382EBBb8A",
"LiFuelFeeCollector": "0x94EA56D8049e93E0308B9c7d1418Baf6A7C68280",
"TokenWrapper": "0xF63b27AE2Dc887b88f82E2Cc597d07fBB2E78E70"
"TokenWrapper": "0xF63b27AE2Dc887b88f82E2Cc597d07fBB2E78E70",
"Permit2Proxy": "0x442BBFD6a4641B2b710DFfa4754081eC7502a3F7"
}
1 change: 1 addition & 0 deletions lib/Permit2
Submodule Permit2 added at cc56ad
2 changes: 1 addition & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ celer-network/=lib/sgn-v2-contracts/
create3-factory/=lib/create3-factory/src/
solmate/=lib/solmate/src/
solady/=lib/solady/src/

permit2/=lib/Permit2/src/
ds-test/=lib/ds-test/src/
forge-std/=lib/forge-std/src/

Expand Down
120 changes: 120 additions & 0 deletions script/demoScripts/demoPermit2Proxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import {
http,
createPublicClient,
parseAbi,
Hex,
parseUnits,
serializeSignature,
createWalletClient,
} from 'viem'
import { privateKeyToAccount, sign } from 'viem/accounts'
import { arbitrum } from 'viem/chains'
import { defineCommand, runMain } from 'citty'

const DIAMOND_ADDRESS = '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'
const USDT_ADDRESS = '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9'
const PERMIT2_PROXY_ADDRESS = '0x442BBFD6a4641B2b710DFfa4754081eC7502a3F7'
const PERMIT2_ADDRESS = '0x000000000022D473030F116dDEE9F6B43aC78BA3'
const PRIVATE_KEY = `0x${process.env.PRIVATE_KEY}`

const main = defineCommand({
meta: {
name: 'demo-permit2',
description: 'Demonstrate a Permit2 tx',
},
args: {
signerKey: {
type: 'string',
description: 'Private key of signer',
required: true,
},
executorKey: {
type: 'string',
description: 'Private key of the executor',
required: true,
},
},
async run({ args }) {
const SIGNER_PRIVATE_KEY = `0x${args.signerKey}` as Hex
const EXECUTOR_PRIVATE_KEY = `0x${args.executorKey}` as Hex

// Setup the required ABIs
const permit2Abi = parseAbi([
'function nonceBitmap(address owner, uint256 index) external view returns (uint256 nonce)',
])
const permit2ProxyAbi = parseAbi([
'function getPermit2MsgHash(address,bytes,address,uint256,uint256,uint256) external view returns (bytes32)',
'function callDiamondWithPermit2SignatureSingle(address,bytes,address,((address,uint256),uint256,uint256),bytes) external',
])

// Setup a READ-ONLY client
const client = createPublicClient({
chain: arbitrum,
transport: http(),
})

// Setup a signer account
const account = privateKeyToAccount(SIGNER_PRIVATE_KEY)

// Get calldata to bridge USDT from LIFI API
const url =
'https://li.quest/v1/quote?fromChain=ARB&toChain=POL&fromToken=0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9&toToken=0xc2132D05D31c914a87C6611C10748AEb04B58e8F&fromAddress=0xb9c0dE368BECE5e76B52545a8E377a4C118f597B&toAddress=0xb9c0dE368BECE5e76B52545a8E377a4C118f597B&fromAmount=5000000'
const options = { method: 'GET', headers: { accept: 'application/json' } }
const lifiResp = await fetch(url, options)
const calldata = (await lifiResp.json()).transactionRequest.data

// Get the nonce from the PERMIT2 contract
const nonce = await client.readContract({
address: PERMIT2_ADDRESS,
abi: permit2Abi,
functionName: 'nonceBitmap',
args: [account.address, 0n],
})

// Get lastest block
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
const block = await client.getBlock()

// Consturct a valid message hash to sign using Permit2Proxy's utility func
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
const msgHash = await client.readContract({
address: PERMIT2_PROXY_ADDRESS,
abi: permit2ProxyAbi,
functionName: 'getPermit2MsgHash',
args: [
DIAMOND_ADDRESS,
calldata,
USDT_ADDRESS,
parseUnits('5', 6),
nonce,
block.timestamp + 1200n,
],
})
console.log(msgHash)

// Sign the message hash
const rsvSig = await sign({ hash: msgHash, privateKey: SIGNER_PRIVATE_KEY })
const signature = serializeSignature(rsvSig)
console.log(signature)

// Setup the parameters for the executor to call
const tokenPermissions = [USDT_ADDRESS, parseUnits('5', 6)]
const permit = [tokenPermissions, nonce, block.timestamp + 1200n]
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved

// Instantiate the executor account and a WRITE enabled client
const executorAccount = privateKeyToAccount(EXECUTOR_PRIVATE_KEY)
const walletClient = createWalletClient({
account: executorAccount,
chain: arbitrum,
transport: http(),
})

// Execute using the Permit2 Proxy
const tx = await walletClient.writeContract({
address: PERMIT2_PROXY_ADDRESS,
abi: permit2ProxyAbi,
functionName: 'callDiamondWithPermit2SignatureSingle',
args: [DIAMOND_ADDRESS, calldata, account.address, permit, signature],
})
},
})

ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
runMain(main)
53 changes: 53 additions & 0 deletions script/deploy/facets/DeployPermit2Proxy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import { DeployScriptBase } from "./utils/DeployScriptBase.sol";
import { Permit2Proxy } from "lifi/Periphery/Permit2Proxy.sol";
import { stdJson } from "forge-std/Script.sol";

contract DeployScript is DeployScriptBase {
using stdJson for string;

constructor() DeployScriptBase("Permit2Proxy") {}

function run()
public
returns (Permit2Proxy deployed, bytes memory constructorArgs)
{
constructorArgs = getConstructorArgs();

deployed = Permit2Proxy(deploy(type(Permit2Proxy).creationCode));
}
0xDEnYO marked this conversation as resolved.
Show resolved Hide resolved

function getConstructorArgs() internal override returns (bytes memory) {
// get path of global config file
string memory globalConfigPath = string.concat(
root,
"/config/global.json"
);

// read file into json variable
string memory globalConfigJson = vm.readFile(globalConfigPath);

// extract refundWallet address
address deployWalletAddress = globalConfigJson.readAddress(
".deployerWallet"
);

// get path of permit2 config file
string memory permit2ProxyConfig = string.concat(
root,
"/config/permit2.json"
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
);

// read file into json variable
string memory permit2ProxyConfigJSON = vm.readFile(permit2ProxyConfig);

// extract wrapped token address for the given network
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
address permit2Address = permit2ProxyConfigJSON.readAddress(
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
string.concat(".", network)
);

return abi.encode(deployWalletAddress, permit2Address);
}
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading