-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
604 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { ethers } from "ethers"; | ||
|
||
const ERC20_ABI = [ | ||
"function approve(address spender, uint256 amount) external returns (bool)", | ||
"function allowance(address owner, address spender) external view returns (uint256)" | ||
] | ||
|
||
const BRIDGE_ABI = [ | ||
"function withdraw(address token, address to, uint256 amount, bool needUnwrap, bytes signature, uint256 transferFee, uint256 bridgeFee) payable", | ||
"function wrapWithdraw(address to, bytes signature, uint256 transferFee, uint256 bridgeFee) payable" | ||
] | ||
|
||
export const erc20Contract = new ethers.Contract(ethers.constants.AddressZero, ERC20_ABI) | ||
export const bridgeContract = new ethers.Contract(ethers.constants.AddressZero, BRIDGE_ABI) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { BridgeAddresses, BridgeNetwork, Config, ConfigToken, Network, Token } from "./types"; | ||
import { isAddress } from "ethers/lib/utils"; | ||
|
||
|
||
export function formatBridgeAddresses(config: Config): BridgeAddresses { | ||
const result: BridgeAddresses = {}; | ||
|
||
for (const [network, { amb, side }] of Object.entries(config.bridges)) { | ||
if (!result['amb']) result['amb'] = {} | ||
if (!result[network]) result[network] = {} | ||
|
||
result['amb'][network] = amb | ||
result[network]['amb'] = side | ||
} | ||
|
||
return result; | ||
} | ||
|
||
export function getPairs(configFile: Config, sourceNetwork: Network, destinationNetwork: Network) { | ||
const bridgeNetwork = detectBridgeNetwork(sourceNetwork, destinationNetwork); | ||
|
||
const tokenPairs: [Token, Token][] = []; | ||
|
||
// NOTE: only one of destination tokens can be the wrapper for native coin | ||
// if there are multiple - we need to select the latest occurrence in config (it's restriction of a contracts implementation) | ||
// and it's already a case with multiple tokens: SAMB and SAMB2 in eth->amb bridge | ||
// so, reverse tokens array and store the `isAnyDestinationNativeWrapper` flag | ||
|
||
const tokens = Object.values(configFile.tokens).reverse() | ||
let isAnyDestinationNativeWrapper = false; | ||
|
||
for (const token of tokens) { | ||
if (!token.isActive) | ||
continue; | ||
|
||
const [tokenSource, tokenDest] = [token.networks[sourceNetwork], token.networks[destinationNetwork]]; | ||
|
||
// token must be deployed on both sides | ||
if (!isAddress(tokenSource?.address) || !isAddress(tokenDest?.address)) | ||
continue | ||
|
||
const createPair = (nativeSource: boolean, nativeDest: boolean): [Token, Token] => [ | ||
createToken(token, bridgeNetwork, sourceNetwork, nativeSource), | ||
createToken(token, bridgeNetwork, destinationNetwork, nativeDest) | ||
]; | ||
|
||
// create erc20 -> erc20 pair | ||
tokenPairs.push(createPair(false, false)); | ||
|
||
// create native -> erc20 if need | ||
if (tokenSource.isPrimary && tokenSource.nativeCoin) | ||
tokenPairs.push(createPair(true, false)); | ||
|
||
// create erc20 -> native if need | ||
if (tokenDest.isPrimary && tokenDest.nativeCoin && !isAnyDestinationNativeWrapper) { | ||
tokenPairs.push(createPair(false, true)); | ||
isAnyDestinationNativeWrapper = true; | ||
} | ||
} | ||
|
||
return tokenPairs; | ||
} | ||
|
||
|
||
function createToken(configToken: ConfigToken, bridgeNetwork: BridgeNetwork, network: Network, isNativeCoin: boolean): Token { | ||
const networkToken = configToken.networks[network] | ||
|
||
return { | ||
name: configToken.name, | ||
symbol: configToken.symbol, | ||
address: networkToken.address, | ||
decimals: networkToken.denomination, | ||
isNativeCoin, | ||
network, | ||
bridgeNetwork | ||
} | ||
} | ||
|
||
|
||
function detectBridgeNetwork(sourceNetwork: Network, destinationNetwork: Network): BridgeNetwork { | ||
if (sourceNetwork === destinationNetwork) throw new Error("sourceNetwork and destinationNetwork must be different"); | ||
if (sourceNetwork !== "amb") return sourceNetwork; | ||
if (destinationNetwork !== "amb") return destinationNetwork; | ||
throw new Error("can't be") | ||
} |
Oops, something went wrong.