Skip to content

Commit

Permalink
Merge pull request #43 from 1inch/feat/zksync-escrow-factory
Browse files Browse the repository at this point in the history
feat: zksync address generation for escrow factory
  • Loading branch information
rharutyunyan authored Oct 31, 2024
2 parents b3d755a + e3326e2 commit 793b1ce
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 8 deletions.
100 changes: 100 additions & 0 deletions src/escrow-factory/escrow-factory-facade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {Address, Interaction, NetworkEnum} from '@1inch/fusion-sdk'
import {EscrowFactory} from './escrow-factory'
import {EscrowFactoryZksync} from './escrow-factory-zksync'
import {DstImmutablesComplement, Immutables} from '../immutables'
import {MerkleLeaf} from '../cross-chain-order/hash-lock/hash-lock'

export class EscrowFactoryFacade implements EscrowFactory {
private factory: EscrowFactory

constructor(chainId: NetworkEnum, factoryAddress: Address) {
this.factory = EscrowFactoryFacade.getFactory(chainId, factoryAddress)
}

get address(): Address {
return this.factory.address
}

public static getFactory(
chainId: NetworkEnum,
factoryAddress: Address
): EscrowFactory {
switch (chainId) {
case NetworkEnum.ZKSYNC:
return new EscrowFactoryZksync(factoryAddress)
default:
return new EscrowFactory(factoryAddress)
}
}

public getEscrowAddress(
/**
* @see Immutables.hash
*/
immutablesHash: string,
/**
* Address of escrow implementation at the same chain as `this.address`
*/
implementationAddress: Address
): Address {
return this.factory.getEscrowAddress(
immutablesHash,
implementationAddress
)
}

public getSrcEscrowAddress(
/**
* From `SrcEscrowCreated` event (with correct timeLock.deployedAt)
*/
srcImmutables: Immutables,
/**
* Address of escrow implementation at the same chain as `this.address`
*/
implementationAddress: Address
): Address {
return this.factory.getSrcEscrowAddress(
srcImmutables,
implementationAddress
)
}

public getDstEscrowAddress(
/**
* From `SrcEscrowCreated` event
*/
srcImmutables: Immutables,
/**
* From `SrcEscrowCreated` event
*/
complement: DstImmutablesComplement,
/**
* Block time when event `DstEscrowCreated` produced
*/
blockTime: bigint,
/**
* Taker from `DstEscrowCreated` event
*/
taker: Address,
/**
* Address of escrow implementation at the same chain as `this.address`
*/
implementationAddress: Address
): Address {
return this.getDstEscrowAddress(
srcImmutables,
complement,
blockTime,
taker,
implementationAddress
)
}

public getMultipleFillInteraction(
proof: MerkleLeaf[],
idx: number,
secretHash: string
): Interaction {
return this.factory.getMultipleFillInteraction(proof, idx, secretHash)
}
}
56 changes: 56 additions & 0 deletions src/escrow-factory/escrow-factory-zksync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {Address} from '@1inch/fusion-sdk'
import {AbiCoder, concat, keccak256} from 'ethers'
import {add0x, getBytesCount, isHexBytes, trim0x} from '@1inch/byte-utils'
import assert from 'assert'
import {EscrowFactory} from './escrow-factory'

export class EscrowFactoryZksync extends EscrowFactory {
private static create2Prefix =
'0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494'

/**
* ZkSync proxy bytecode do not depends on implementation address
*
* @see proxy example - https://explorer.zksync.io/address/0xd5317Ded4FBb98526AdD35A15d63cFBFB929efc7
*/
private static minimalProxyBytecodeHash =
'0x01000035492ceb24a47d861a8fd7e65b117f2eb5bf6453e191ba770c70ca7f43'

/**
* Calculate address of escrow contract in ZkSync Era
*
* @return escrow address at same the chain as `this.address`
*/
public override getEscrowAddress(
/**
* @see Immutables.hash
*/
immutablesHash: string,
/**
* Address of escrow implementation at the same chain as `this.address`
*/
implementationAddress: Address
): Address {
assert(
isHexBytes(immutablesHash) && getBytesCount(immutablesHash) === 32n,
'invalid hash'
)

const inputHash = keccak256(
AbiCoder.defaultAbiCoder().encode(
['address'],
[implementationAddress.toString()]
)
)

const concatenatedData = concat([
EscrowFactoryZksync.create2Prefix,
add0x(trim0x(this.address.toString()).padStart(64, '0')),
immutablesHash,
EscrowFactoryZksync.minimalProxyBytecodeHash,
inputHash
])

return new Address(add0x(keccak256(concatenatedData).slice(-40)))
}
}
94 changes: 87 additions & 7 deletions src/escrow-factory/escrow-factory.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import {Address} from '@1inch/fusion-sdk'
import {Address, NetworkEnum} from '@1inch/fusion-sdk'
import {keccak256} from 'ethers'
import {EscrowFactory} from './escrow-factory'
import {EscrowFactoryFacade} from './escrow-factory-facade'
import {EscrowFactoryZksync} from './escrow-factory-zksync'
import {Immutables} from '../immutables'
import {HashLock, TimeLocks} from '../cross-chain-order'

describe('EscrowFactory', () => {
it('Should correct calc src/dst address', () => {
const factory = new EscrowFactory(Address.fromBigInt(1n))
describe('EscrowAddressFacade', () => {
it('Should correct calc src/dst address for Ethereum', () => {
const facade = new EscrowFactoryFacade(
NetworkEnum.ETHEREUM,
Address.fromBigInt(1n)
)
const immutablesHash = keccak256('0x')
const srcImplAddress = Address.fromBigInt(1n)
const dstImplAddress = Address.fromBigInt(2n)
const srcAddress = factory.getEscrowAddress(

const srcAddress = facade.getEscrowAddress(
immutablesHash,
srcImplAddress
)
const dstAddress = factory.getEscrowAddress(
const dstAddress = facade.getEscrowAddress(
immutablesHash,
dstImplAddress
)
Expand All @@ -25,4 +32,77 @@ describe('EscrowFactory', () => {
new Address('0x291200ceb5fab3847c9f30c5f272961f78d6cfd4')
)
})

describe('zkSync', () => {
it('Should calc correct src address from immutables', () => {
const immutables = Immutables.new({
maker: new Address(
'0x04d3b2c70208f3fb196affef78080b3cc05ee1cb'
),
taker: new Address(
'0x9c4dffb4f7e8217a8ac0555d67e125f8769284ba'
),
token: new Address(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
),
amount: 99345341n,
hashLock: HashLock.fromString(
'0x939dbeb956ac9369de8b1acaaa78a173620c2275fba501f8340b91cbceabdbf1'
),
orderHash:
'0x8ed7de0668228e00103038a7fc6a19c933d56fca27b154a3e532ebeb4a5c07bd',
timeLocks:
TimeLocks.fromBigInt(
46545443980783778519496226194286874737220106048808714334632784681655911579684n
),
safetyDeposit: 2474844692460000n
})

const factory = new EscrowFactoryZksync(
new Address('0x584aEaB186D81dbB52a8a14820c573480c3d4773')
)

expect(
factory.getSrcEscrowAddress(
immutables,
new Address('0xddc60c7babfc55d8030f51910b157e179f7a41fc')
)
).toEqual(new Address('0x98f0a945348c031f85164562bff61eb08a0629df'))
})
it('Should calc correct dst address from immutables', () => {
const immutables = Immutables.new({
maker: new Address(
'0x04d3b2c70208f3fb196affef78080b3cc05ee1cb'
),
taker: new Address(
'0x9c4dffb4f7e8217a8ac0555d67e125f8769284ba'
),
token: new Address(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
),
amount: 99345341n,
hashLock: HashLock.fromString(
'0x939dbeb956ac9369de8b1acaaa78a173620c2275fba501f8340b91cbceabdbf1'
),
orderHash:
'0x8ed7de0668228e00103038a7fc6a19c933d56fca27b154a3e532ebeb4a5c07bd',
timeLocks:
TimeLocks.fromBigInt(
46545443980783778519496226194286874737220106048808714334632784681655911579684n
),
safetyDeposit: 2474844692460000n
})

const factory = new EscrowFactoryZksync(
new Address('0x584aEaB186D81dbB52a8a14820c573480c3d4773')
)

expect(
factory.getEscrowAddress(
immutables.hash(),
new Address('0xdc4ccc2fc2475d0ed3fddd563c44f2bf6a3900c9')
)
).toEqual(new Address('0x93d8a039c23cffd1067e02edbdd28189ac679a39'))
})
})
})
2 changes: 1 addition & 1 deletion src/escrow-factory/escrow-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class EscrowFactory {
/**
* See https://github.com/1inch/cross-chain-swap/blob/03d99b9604d8f7a5a396720fbe1059f7d94db762/contracts/libraries/ProxyHashLib.sol#L14
*/
private static calcProxyBytecodeHash(impl: Address): string {
protected static calcProxyBytecodeHash(impl: Address): string {
return keccak256(
`0x3d602d80600a3d3981f3363d3d373d3d3d363d73${trim0x(impl.toString())}5af43d82803e903d91602b57fd5bf3`
)
Expand Down

0 comments on commit 793b1ce

Please sign in to comment.