LiquidityManager
Handles liquidity deposits and withdrawals for the ERC20 bridge

Functions

addLiquidityERC20

Adds ERC20 liquidity to an existing pool or creates a new one, if it does not exist yet
1
function addLiquidityERC20(IERC20 token, uint256 amount) external override nonReentrant {
2
// check ERC20 bridge token balance before deposit
3
uint256 balanceBefore = token.balanceOf(address(bridgeERC20));
4
5
// Transfer token amount from sender to ERC20bridge
6
token.safeTransferFrom(_msgSender(), address(bridgeERC20), amount);
7
8
// check if ERC20 bridge token balance has increased by amount (>> effectively preventing deflationary tokens to be added for now)
9
if (token.balanceOf(address(bridgeERC20)) != balanceBefore + amount) revert OperationFailed();
10
11
// call internal function to mint LP tokens and emit event
12
_addLiquidityERC20(token, amount);
13
14
// forward the minted LP tokens to msg_sender()
15
IERC20(address(lpTokens[address(token)].token)).safeTransfer(_msgSender(), amount);
16
}
Copied!

Parameters:

Name
Type
Description
token
IERC20
the address of the token for which liquidity should be added
amount
uint256
the amount of tokens to be added

addLiquidityNative

Adds native liquidity to the ERC20 bridge
1
function addLiquidityNative(uint256 amount) external payable override nonReentrant {
2
// check input parameters
3
if (amount != msg.value) revert InvalidMessageValue(msg.value, amount);
4
5
// check native token balance before call
6
uint256 contractBalance = wrappedNative.balanceOf(address(this));
7
8
// swap native to wrapped native ERC20 token
9
wrappedNative.deposit{value: msg.value}();
10
11
// check if wrapped native token balance has increased by deposit amount
12
if (wrappedNative.balanceOf(address(this)) != contractBalance + amount) revert OperationFailed();
13
14
// Transfer ERC20 tokens from this contract to ERC20bridge
15
IERC20(wrappedNative).safeTransfer(address(bridgeERC20), amount);
16
17
// call addLiquidityERC20 function with wrapped native token
18
_addLiquidityERC20(wrappedNative, amount);
19
20
// transfer LP tokens from this contract to msg.sender to complete the transaction
21
lpTokens[address(wrappedNative)].token.safeTransfer(_msgSender(), amount);
22
}
Copied!

Parameters:

Name
Type
Description
amount
uint256
the amount of tokens to be added

withdrawLiquidityERC20

Removes liquidity from the ERC20 bridge
1
function withdrawLiquidityERC20(IERC20 token, uint256 amount) external override nonReentrant {
2
// burn LP token in the amount of liquidity that should be removed
3
ERC20Burnable(address(lpTokens[address(token)].token)).burnFrom(_msgSender(), amount);
4
// call internal function to calculate fee and emit event
5
uint256 withdrawalAmount = _withdrawLiquidityERC20(token, amount);
6
7
// safely transfer token amount minus fees to the sender
8
token.safeTransferFrom(address(bridgeERC20), _msgSender(), withdrawalAmount);
9
}
Copied!

Parameters:

Name
Type
Description
token
IERC20
the address of the token for which liquidity should be removed
amount
uint256
the amount of tokens to be added

withdrawLiquidityNative

Removes native liquidity from the ERC20 bridge
1
function withdrawLiquidityNative(uint256 withdrawalAmount) external override nonReentrant {
2
// check if liquidity is sufficient
3
if (wrappedNative.balanceOf(address(bridgeERC20)) < withdrawalAmount) revert InvalidBalance();
4
5
// transfer LP tokens from msgSender to this contract
6
lpTokens[address(wrappedNative)].token.safeTransferFrom(_msgSender(), address(this), withdrawalAmount);
7
8
// check wrapped native token balance before ERC20 withdrawal
9
uint256 contractBalance = wrappedNative.balanceOf(address(this));
10
11
// withdraw ERC20 liquidity from bridge
12
uint256 withdrawalAmountAfterFees = _withdrawLiquidityERC20(wrappedNative, withdrawalAmount);
13
14
// transfer ERC20 tokens (minus fees) from bridge to this contract
15
IERC20(wrappedNative).safeTransferFrom(address(bridgeERC20), address(this), withdrawalAmountAfterFees);
16
17
// check wrapped native token balance after ERC20 withdrawal
18
if (wrappedNative.balanceOf(address(this)) != contractBalance + withdrawalAmountAfterFees) revert OperationFailed();
19
20
// check native token balance before call
21
contractBalance = address(this).balance;
22
23
// swap wrapped native ERC20 token back to native token
24
wrappedNative.withdraw(withdrawalAmountAfterFees);
25
26
// check if native token balance has increased by withdraw amount
27
if (address(this).balance != contractBalance + withdrawalAmountAfterFees) revert OperationFailed();
28
29
// send native token back to user
30
payable(_msgSender()).transfer(withdrawalAmountAfterFees);
31
}
Copied!

Parameters:

Name
Type
Description
withdrawalAmount
uint256
the amount of tokens to be added