Skip to content

Commit

Permalink
feat: zksync address generation for escrow factory
Browse files Browse the repository at this point in the history
  • Loading branch information
rharutyunyan committed Oct 29, 2024
1 parent b3d755a commit 4faaec0
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 6 deletions.
113 changes: 113 additions & 0 deletions src/escrow-factory/escrow-factory-facade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import {Address, NetworkEnum} from '@1inch/fusion-sdk'
import {EscrowFactory} from './escrow-factory'
import {DstImmutablesComplement, Immutables} from '../immutables'

export class EscrowFactoryFacade {
private factory: EscrowFactory

constructor(factoryAddress: Address) {
this.factory = new EscrowFactory(factoryAddress)
}

public getEscrowAddressByChain(
/**
* chain id
*/
chainId: number,
/**
* @see Immutables.hash
*/
immutablesHash: string,
/**
* Address of escrow implementation at the same chain as `this.address`
*/
implementationAddress: Address
): Address {
switch (chainId) {
case NetworkEnum.ZKSYNC:
return this.factory.getZkEscrowAddress(
immutablesHash,
implementationAddress
)
default:
return this.factory.getEscrowAddress(
immutablesHash,
implementationAddress
)
}
}

public getSrcEscrowAddressByChain(
/**
* chain id
*/
chainId: number,
/**
* From `SrcEscrowCreated` event (with correct timeLock.deployedAt)
*/
srcImmutables: Immutables,
/**
* Address of escrow implementation at the same chain as `this.address`
*/
implementationAddress: Address
): Address {
switch (chainId) {
case NetworkEnum.ZKSYNC:
return this.factory.getZkSrcEscrowAddress(
srcImmutables,
implementationAddress
)
default:
return this.factory.getSrcEscrowAddress(
srcImmutables,
implementationAddress
)
}
}

public getDstEscrowAddressByChain(
/**
* chain id
*/
chainId: number,
/**
* 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 {
switch (chainId) {
case NetworkEnum.ZKSYNC:
return this.factory.getZkDstEscrowAddress(
srcImmutables,
complement,
blockTime,
taker,
implementationAddress
)
default:
return this.factory.getDstEscrowAddress(
srcImmutables,
complement,
blockTime,
taker,
implementationAddress
)
}
}
}
41 changes: 35 additions & 6 deletions src/escrow-factory/escrow-factory.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import {Address} from '@1inch/fusion-sdk'
import {keccak256} from 'ethers'
import {EscrowFactory} from './escrow-factory'
import {EscrowFactoryFacade} from './escrow-factory-facade'

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(Address.fromBigInt(1n))
const immutablesHash = keccak256('0x')
const srcImplAddress = Address.fromBigInt(1n)
const dstImplAddress = Address.fromBigInt(2n)
const srcAddress = factory.getEscrowAddress(

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

it('Should correct calc zk src/dst address for zkSync', () => {
const facade = new EscrowFactoryFacade(Address.fromBigInt(1n))
const immutablesHash = keccak256('0x')
const srcImplAddress = Address.fromBigInt(1n)
const dstImplAddress = Address.fromBigInt(2n)

const srcAddress = facade.getEscrowAddressByChain(
324,
immutablesHash,
srcImplAddress
)
const dstAddress = facade.getEscrowAddressByChain(
324,
immutablesHash,
dstImplAddress
)

expect(srcAddress).toEqual(
new Address('0x48f33ed21a3ab24b699fc2f709266f86b0c5714e')
)

expect(dstAddress).toEqual(
new Address('0x68460df9d1f08e7eaff280cb880d9be59b2143b7')
)
})
})
90 changes: 90 additions & 0 deletions src/escrow-factory/escrow-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,96 @@ export class EscrowFactory {
)
}

/**
* Calculate address of escrow contract in ZkSync Era
*
* @return escrow address at same the chain as `this.address`
*/
public getZkEscrowAddress(
/**
* @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 bytecodeHash = EscrowFactory.calcProxyBytecodeHash(
implementationAddress
)
const srcInputHash = keccak256(implementationAddress.toString())
const create2Prefix =
'0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494'

const concatenatedData = `${create2Prefix}${trim0x(this.address.toString())}${trim0x(immutablesHash)}${trim0x(bytecodeHash)}${trim0x(srcInputHash)}`

return new Address(add0x(keccak256(concatenatedData).slice(-40)))
}

/**
* Calculates source escrow address for given params
*
* Make sure you call it on source chain escrow factory
*/
public getZkSrcEscrowAddress(
/**
* 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.getZkEscrowAddress(
srcImmutables.hash(),
implementationAddress
)
}

/**
* Calculates destination escrow address for given params
*
* Make sure you call it on destination chain escrow factory
*/
public getZkDstEscrowAddress(
/**
* 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.getEscrowAddress(
srcImmutables
.withComplement(complement)
.withTaker(taker)
.withDeployedAt(blockTime)
.hash(),
implementationAddress
)
}

/**
* Calculate address of escrow contract
*
Expand Down

0 comments on commit 4faaec0

Please sign in to comment.