Skip to content
This repository was archived by the owner on Mar 14, 2025. It is now read-only.

Commit 2632051

Browse files
committed
adding zksync wrappers
1 parent 6ac05d7 commit 2632051

File tree

21 files changed

+5497
-144
lines changed

21 files changed

+5497
-144
lines changed

contracts/scripts/native_solc_compile_all_ccip

Lines changed: 59 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ echo " │ Compiling CCIP contracts... │"
77
echo " └──────────────────────────────────────────────┘"
88

99
SOLC_VERSION="0.8.24"
10+
ZKSOLC_VERSION="1.5.3"
1011
OPTIMIZE_RUNS=26000
1112
OPTIMIZE_RUNS_OFFRAMP=18000
1213
OPTIMIZE_RUNS_ONRAMP=4100
@@ -52,56 +53,67 @@ compileContract () {
5253
--bin-runtime --hashes --metadata --metadata-literal --combined-json abi,hashes,metadata,srcmap,srcmap-runtime \
5354
--evm-version paris \
5455
"$ROOT"/contracts/src/v0.8/"$1"
56+
57+
zksolc --overwrite -O3 --metadata-hash none \
58+
-o "$ROOT"/contracts/zksolc/v$ZKSOLC_VERSION/"$contract" \
59+
--bin --allow-paths "$ROOT"/contracts/src/v0.8 \
60+
--metadata-literal \
61+
--evm-version paris \
62+
"$ROOT"/contracts/src/v0.8/"$1"
5563
}
5664

5765

5866
# Solc produces and overwrites intermediary contracts.
5967
# Contracts should be ordered in reverse-import-complexity-order to minimize overwrite risks.
60-
compileContract ccip/offRamp/EVM2EVMOffRamp.sol
61-
compileContract ccip/offRamp/OffRamp.sol
62-
compileContract ccip/applications/PingPongDemo.sol
63-
compileContract ccip/applications/SelfFundedPingPong.sol
64-
compileContract ccip/applications/EtherSenderReceiver.sol
65-
compileContract ccip/onRamp/OnRamp.sol
68+
# compileContract ccip/offRamp/EVM2EVMOffRamp.sol
6669
compileContract ccip/onRamp/EVM2EVMOnRamp.sol
67-
compileContract ccip/CommitStore.sol
68-
compileContract ccip/MultiAggregateRateLimiter.sol
69-
compileContract ccip/Router.sol
70-
compileContract ccip/PriceRegistry.sol
71-
compileContract ccip/RMN.sol
72-
compileContract ccip/ARMProxy.sol
73-
compileContract ccip/tokenAdminRegistry/TokenAdminRegistry.sol
74-
compileContract ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol
75-
compileContract ccip/capability/CCIPConfig.sol
76-
compileContract ccip/capability/interfaces/IOCR3ConfigEncoder.sol
77-
compileContract ccip/NonceManager.sol
78-
compileContract shared/token/ERC677/BurnMintERC677.sol
79-
80-
81-
# Pools
82-
compileContract ccip/pools/LockReleaseTokenPool.sol
83-
compileContract ccip/pools/BurnMintTokenPool.sol
84-
compileContract ccip/pools/BurnFromMintTokenPool.sol
85-
compileContract ccip/pools/BurnWithFromMintTokenPool.sol
86-
compileContract ccip/pools/LockReleaseTokenPoolAndProxy.sol
87-
compileContract ccip/pools/BurnMintTokenPoolAndProxy.sol
88-
compileContract ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol
89-
compileContract ccip/pools/TokenPool.sol
90-
91-
92-
# Test helpers
93-
compileContract ccip/test/helpers/BurnMintERC677Helper.sol
94-
compileContract ccip/test/helpers/CommitStoreHelper.sol
95-
compileContract ccip/test/helpers/MessageHasher.sol
96-
compileContract ccip/test/helpers/CCIPReaderTester.sol
97-
compileContract ccip/test/helpers/ReportCodec.sol
98-
compileContract ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol
99-
compileContract ccip/test/helpers/MultiOCR3Helper.sol
100-
compileContract ccip/test/mocks/MockE2EUSDCTokenMessenger.sol
101-
compileContract ccip/test/mocks/MockE2EUSDCTransmitter.sol
102-
compileContract ccip/test/WETH9.sol
103-
104-
# Customer contracts
105-
compileContract ccip/pools/USDC/USDCTokenPool.sol
106-
107-
compileContract tests/MockV3Aggregator.sol
70+
# compileContract ccip/applications/PingPongDemo.sol
71+
# compileContract ccip/applications/SelfFundedPingPong.sol
72+
# compileContract ccip/CommitStore.sol
73+
# compileContract ccip/Router.sol
74+
# compileContract ccip/PriceRegistry.sol
75+
# compileContract ccip/RMN.sol
76+
# compileContract ccip/ARMProxy.sol
77+
# compileContract ccip/tokenAdminRegistry/TokenAdminRegistry.sol
78+
# compileContract ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol
79+
# compileContract ccip/pools/LockReleaseTokenPool.sol
80+
# compileContract ccip/test/WETH9.sol
81+
# compileContract shared/token/ERC677/LinkToken.sol
82+
83+
84+
# compileContract ccip/offRamp/OffRamp.sol
85+
# compileContract ccip/applications/EtherSenderReceiver.sol
86+
# compileContract ccip/onRamp/OnRamp.sol
87+
# compileContract ccip/MultiAggregateRateLimiter.sol
88+
# compileContract ccip/capability/CCIPConfig.sol
89+
# compileContract ccip/capability/interfaces/IOCR3ConfigEncoder.sol
90+
# compileContract ccip/NonceManager.sol
91+
# compileContract shared/token/ERC677/BurnMintERC677.sol
92+
93+
94+
# # Pools
95+
# compileContract ccip/pools/BurnMintTokenPool.sol
96+
# compileContract ccip/pools/BurnFromMintTokenPool.sol
97+
# compileContract ccip/pools/BurnWithFromMintTokenPool.sol
98+
# compileContract ccip/pools/LockReleaseTokenPoolAndProxy.sol
99+
# compileContract ccip/pools/BurnMintTokenPoolAndProxy.sol
100+
# compileContract ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol
101+
# compileContract ccip/pools/TokenPool.sol
102+
103+
104+
# # Test helpers
105+
# compileContract ccip/test/helpers/BurnMintERC677Helper.sol
106+
# compileContract ccip/test/helpers/CommitStoreHelper.sol
107+
# compileContract ccip/test/helpers/MessageHasher.sol
108+
# compileContract ccip/test/helpers/CCIPReaderTester.sol
109+
# compileContract ccip/test/helpers/ReportCodec.sol
110+
# compileContract ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol
111+
# compileContract ccip/test/helpers/MultiOCR3Helper.sol
112+
# compileContract ccip/test/mocks/MockE2EUSDCTokenMessenger.sol
113+
# compileContract ccip/test/mocks/MockE2EUSDCTransmitter.sol
114+
115+
116+
# # Customer contracts
117+
# compileContract ccip/pools/USDC/USDCTokenPool.sol
118+
119+
# compileContract tests/MockV3Aggregator.sol

contracts/src/v0.8/ccip/test/WETH9.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ contract WETH9 {
4343
_deposit();
4444
}
4545

46-
function withdraw(uint256 wad) external {
46+
function withdraw(uint256 wad) public {
4747
require(balanceOf[msg.sender] >= wad);
4848
balanceOf[msg.sender] -= wad;
49-
payable(msg.sender).transfer(wad);
49+
// Replace transfer with call
50+
(bool success,) = payable(msg.sender).call{value: wad}("");
51+
require(success, "WETH9: ETH transfer failed");
5052
emit Withdrawal(msg.sender, wad);
5153
}
5254

core/gethwrappers/abigen.go

Lines changed: 196 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const headerComment = `// Code generated - DO NOT EDIT.
2828
// AbigenArgs is the arguments to the abigen executable. E.g., Bin is the -bin
2929
// arg.
3030
type AbigenArgs struct {
31-
Bin, ABI, Out, Type, Pkg string
31+
Bin, ABI, Out, Type, Pkg, ZkBinPath string
3232
}
3333

3434
// Abigen calls Abigen with the given arguments
@@ -72,6 +72,9 @@ func Abigen(a AbigenArgs) {
7272
}
7373

7474
ImproveAbigenOutput(a.Out, a.ABI)
75+
if a.ZkBinPath != "" {
76+
ImproveAbigenOutputZks(a.Out, a.ZkBinPath)
77+
}
7578
}
7679

7780
func ImproveAbigenOutput(path string, abiPath string) {
@@ -466,3 +469,195 @@ func writeInterface(contractName string, fileNode *ast.File) *ast.File {
466469
func addHeader(code []byte) []byte {
467470
return utils.ConcatBytes([]byte(headerComment), code)
468471
}
472+
473+
// ZK stack logic
474+
func ImproveAbigenOutputZks(path string, zkBinPath string) {
475+
bs, err := os.ReadFile(path)
476+
if err != nil {
477+
Exit("Error while improving abigen output", err)
478+
}
479+
480+
fset, fileNode := parseFile(bs)
481+
482+
contractName := getContractName(fileNode)
483+
484+
zkByteCode, err := os.ReadFile(zkBinPath)
485+
if err != nil {
486+
Exit("Error while improving abigen output", err)
487+
}
488+
zkHexString := string(zkByteCode)
489+
490+
// add zksync binary to the wrapper
491+
fileNode = addZKSyncBin(fileNode, contractName, zkHexString)
492+
493+
// add zksync logic to the deploy function
494+
fileNode = updateDeployMethod(contractName, fset, fileNode)
495+
496+
bs = generateCode(fset, fileNode)
497+
498+
err = os.WriteFile(path, bs, 0600)
499+
if err != nil {
500+
Exit("Error while writing improved abigen source", err)
501+
}
502+
}
503+
504+
// add zksync binary to the wrapper
505+
func addZKSyncBin(fileNode *ast.File, contractName string, zkHexString string) *ast.File {
506+
// zksync
507+
newVarSpec := &ast.ValueSpec{
508+
Names: []*ast.Ident{ast.NewIdent(contractName + "ZKBin")},
509+
Values: []ast.Expr{
510+
&ast.BasicLit{
511+
Kind: token.STRING,
512+
Value: fmt.Sprintf("(\"%s\")", zkHexString),
513+
},
514+
},
515+
}
516+
newVarDecl := &ast.GenDecl{
517+
Tok: token.VAR,
518+
Specs: []ast.Spec{newVarSpec},
519+
}
520+
521+
// Insert the new variable declaration at the top of the file (before existing functions)
522+
fileNode.Decls = append(fileNode.Decls, newVarDecl)
523+
return fileNode
524+
}
525+
526+
// add zksync logic to the deploy function
527+
func updateDeployMethod(contractName string, fset *token.FileSet, fileNode *ast.File) *ast.File {
528+
529+
return astutil.Apply(fileNode, func(cursor *astutil.Cursor) bool {
530+
x, is := cursor.Node().(*ast.FuncDecl)
531+
if !is {
532+
return true
533+
} else if x.Name.Name != "Deploy"+contractName {
534+
return false
535+
}
536+
537+
// only add this import if Deploy method found
538+
astutil.AddImport(fset, fileNode, "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated")
539+
540+
// Extract the parameters from the existing function x
541+
paramList := getConstructorParams(x.Type.Params.List)
542+
// get the `if zksync()` block
543+
zkSyncBlock := getZKSyncBlock(contractName, paramList)
544+
// insert the `if zksync()` block
545+
addZKSyncBlock(*x, zkSyncBlock)
546+
// update the return type in the function signature
547+
updateTxReturnType(*x)
548+
// update the actual return value
549+
updateReturnStmt(*x)
550+
551+
return false
552+
}, nil).(*ast.File)
553+
}
554+
555+
// get the `if zksync()` block
556+
func getZKSyncBlock(contractName, paramList string) string {
557+
zkSyncBlock := `if generated.IsZKSync(backend) {
558+
address, ethTx, contractBind, _ := generated.DeployContract(auth, parsed, common.FromHex(%sZKBin), backend, %params)
559+
contractReturn := &%s{address: address, abi: *parsed, %sCaller: %sCaller{contract: contractBind}, %sTransactor: %sTransactor{contract: contractBind},%sFilterer: %sFilterer{contract: contractBind}}
560+
return address, ethTx, contractReturn, err
561+
}`
562+
zkSyncBlock = strings.ReplaceAll(zkSyncBlock, "%s", contractName)
563+
zkSyncBlock = strings.ReplaceAll(zkSyncBlock, "%params", paramList)
564+
return strings.ReplaceAll(zkSyncBlock, "%s", contractName)
565+
}
566+
567+
// Extract the parameters for constructor function
568+
func getConstructorParams(contstructorParams []*ast.Field) string {
569+
params := []string{}
570+
for i, param := range contstructorParams {
571+
if i > 1 { // Skip auth and backend
572+
for _, name := range param.Names {
573+
params = append(params, name.Name)
574+
}
575+
}
576+
}
577+
paramList := strings.Join(params, ", ")
578+
return paramList
579+
}
580+
581+
// insert the `if zksync()` block
582+
func addZKSyncBlock(x ast.FuncDecl, zkSyncBlock string) ast.FuncDecl {
583+
for i, stmt := range x.Body.List {
584+
585+
ifStmt, ok := stmt.(*ast.IfStmt)
586+
if !ok {
587+
continue
588+
}
589+
binaryExpr, ok := ifStmt.Cond.(*ast.BinaryExpr)
590+
if !ok {
591+
continue
592+
}
593+
if ident, ok := binaryExpr.X.(*ast.Ident); ok && ident.Name == "parsed" {
594+
// Creating new statement to insert
595+
newStmt := &ast.ExprStmt{
596+
X: &ast.BasicLit{
597+
Kind: token.STRING,
598+
Value: zkSyncBlock,
599+
},
600+
}
601+
602+
// Insert the new statement after the current statement
603+
x.Body.List = append(x.Body.List[:i+1], append([]ast.Stmt{newStmt}, x.Body.List[i+1:]...)...)
604+
break
605+
}
606+
}
607+
return x
608+
}
609+
610+
// convert *types.Transaction to *generated_zks.Transaction
611+
func updateTxReturnType(x ast.FuncDecl) {
612+
x.Type.Results.List[1].Type = &ast.StarExpr{
613+
X: &ast.SelectorExpr{
614+
X: &ast.Ident{Name: "generated"},
615+
Sel: &ast.Ident{Name: "Transaction"},
616+
},
617+
}
618+
}
619+
620+
// convert tx to &Transaction{Transaction: tx, HashZks: tx.Hash()}
621+
func updateReturnStmt(x ast.FuncDecl) {
622+
for _, stmt := range x.Body.List {
623+
returnStmt, is := stmt.(*ast.ReturnStmt)
624+
if !is {
625+
continue
626+
}
627+
if len(returnStmt.Results) < 3 {
628+
continue
629+
}
630+
631+
txExpr, ok := returnStmt.Results[1].(*ast.Ident)
632+
if !ok {
633+
return
634+
}
635+
if txExpr.Name != "tx" {
636+
return
637+
}
638+
639+
txField := &ast.KeyValueExpr{
640+
Key: ast.NewIdent("Transaction"),
641+
Value: ast.NewIdent("tx"),
642+
}
643+
644+
hashField := &ast.KeyValueExpr{
645+
Key: ast.NewIdent("HashZks"),
646+
Value: &ast.CallExpr{
647+
Fun: &ast.SelectorExpr{
648+
X: ast.NewIdent("tx"),
649+
Sel: ast.NewIdent("Hash"),
650+
},
651+
},
652+
}
653+
newRet := &ast.CompositeLit{
654+
Type: &ast.SelectorExpr{
655+
X: ast.NewIdent("generated"),
656+
Sel: ast.NewIdent("Transaction"),
657+
},
658+
Elts: []ast.Expr{txField, hashField},
659+
}
660+
pointerRet := &ast.UnaryExpr{Op: token.AND, X: newRet}
661+
returnStmt.Results[1] = pointerRet
662+
}
663+
}

core/gethwrappers/ccip/generated/commit_store/commit_store.go

Lines changed: 9 additions & 6 deletions
Large diffs are not rendered by default.

core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go

Lines changed: 9 additions & 6 deletions
Large diffs are not rendered by default.

core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go

Lines changed: 9 additions & 6 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)