Skip to content

Commit

Permalink
add possibility to depost 0 tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
kovalgek committed Nov 9, 2023
1 parent eb98d0b commit 800e33f
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 53 deletions.
4 changes: 2 additions & 2 deletions contracts/optimism/DepositDataCodec.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ contract DepositDataCodec {
}

DepositData memory depositData;

Check warning

Code scanning / Slither

Uninitialized local variables Medium

DepositDataCodec.decodeDepositData(bytes).depositData is a local variable never initialized
depositData.rate = uint256(bytes32(buffer[0:31]));
depositData.time = uint256(bytes32(buffer[32:63]));
depositData.rate = uint256(bytes32(buffer[0:32]));
depositData.time = uint256(bytes32(buffer[32:64]));
depositData.data = buffer[64:];

return depositData;
Expand Down
53 changes: 35 additions & 18 deletions contracts/optimism/L1ERC20TokenBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,7 @@ contract L1ERC20TokenBridge is
revert ErrorSenderNotEOA();
}

DepositData memory depositData;
depositData.rate = IERC20Wrapable(l1TokenNonRebasable).tokensPerStEth();
depositData.time = block.timestamp;
depositData.data = data_;

bytes memory encodedDepositData = encodeDepositData(depositData);

if (isRebasableTokenFlow(l1Token_, l2Token_)) {
IERC20(l1TokenRebasable).safeTransferFrom(msg.sender, address(this), amount_);
IERC20(l1TokenRebasable).approve(l1TokenNonRebasable, amount_);
uint256 wstETHAmount = IERC20Wrapable(l1TokenNonRebasable).wrap(amount_);
_initiateERC20Deposit(l1TokenRebasable, l2TokenRebasable, msg.sender, msg.sender, wstETHAmount, l2Gas_, encodedDepositData);
} else if (isNonRebasableTokenFlow(l1Token_, l2Token_)) {
IERC20(l1TokenNonRebasable).safeTransferFrom(msg.sender, address(this), amount_);
_initiateERC20Deposit(l1TokenNonRebasable, l2TokenNonRebasable, msg.sender, msg.sender, amount_, l2Gas_, encodedDepositData);
}
_depositERC20To(l1Token_, l2Token_, msg.sender, amount_, l2Gas_, data_);
}

/// @inheritdoc IL1ERC20Bridge
Expand All @@ -101,7 +86,7 @@ contract L1ERC20TokenBridge is
onlySupportedL1Token(l1Token_)
onlySupportedL2Token(l2Token_)
{
_initiateERC20Deposit(l1Token_, l2Token_, msg.sender, to_, amount_, l2Gas_, data_);
_depositERC20To(l1Token_, l2Token_, to_, amount_, l2Gas_, data_);
}

/// @inheritdoc IL1ERC20Bridge
Expand All @@ -123,7 +108,7 @@ contract L1ERC20TokenBridge is
uint256 stETHAmount = IERC20Wrapable(l1TokenNonRebasable).unwrap(amount_);
IERC20(l1TokenRebasable).safeTransfer(to_, stETHAmount);
} else if (isNonRebasableTokenFlow(l1Token_, l2Token_)) {
IERC20(l1Token_).safeTransfer(to_, amount_);
IERC20(l1TokenNonRebasable).safeTransfer(to_, amount_);
}

emit ERC20WithdrawalFinalized(
Expand All @@ -136,6 +121,38 @@ contract L1ERC20TokenBridge is
);
}

function _depositERC20To(
address l1Token_,
address l2Token_,
address to_,
uint256 amount_,
uint32 l2Gas_,
bytes calldata data_
) internal {

DepositData memory depositData;

Check warning

Code scanning / Slither

Uninitialized local variables Medium

depositData.rate = IERC20Wrapable(l1TokenNonRebasable).tokensPerStEth();
depositData.time = block.timestamp;
depositData.data = data_;

bytes memory encodedDepositData = encodeDepositData(depositData);

if (amount_ == 0) {
_initiateERC20Deposit(l1Token_, l2Token_, msg.sender, to_, amount_, l2Gas_, encodedDepositData);
return;
}

if (isRebasableTokenFlow(l1Token_, l2Token_)) {
IERC20(l1TokenRebasable).safeTransferFrom(msg.sender, address(this), amount_);
IERC20(l1TokenRebasable).approve(l1TokenNonRebasable, amount_);
uint256 wstETHAmount = IERC20Wrapable(l1TokenNonRebasable).wrap(amount_);
_initiateERC20Deposit(l1TokenRebasable, l2TokenRebasable, msg.sender, to_, wstETHAmount, l2Gas_, encodedDepositData);
} else if (isNonRebasableTokenFlow(l1Token_, l2Token_)) {
IERC20(l1TokenNonRebasable).safeTransferFrom(msg.sender, address(this), amount_);
_initiateERC20Deposit(l1TokenNonRebasable, l2TokenNonRebasable, msg.sender, to_, amount_, l2Gas_, encodedDepositData);
}
}

/// @dev Performs the logic for deposits by informing the L2 token bridge contract
/// of the deposit and calling safeTransferFrom to lock the L1 funds.
/// @param from_ Account to pull the deposit from on L1
Expand Down
37 changes: 24 additions & 13 deletions contracts/optimism/L2ERC20TokenBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ contract L2ERC20TokenBridge is

address public immutable tokensRateOracle;



/// @param messenger_ L2 messenger address being used for cross-chain communications
/// @param l1TokenBridge_ Address of the corresponding L1 bridge
/// @param l1TokenNonRebasable_ Address of the bridged token in the L1 chain
Expand All @@ -62,20 +60,12 @@ contract L2ERC20TokenBridge is

/// @inheritdoc IL2ERC20Bridge
function withdraw(
address l1Token_,
address l2Token_,
uint256 amount_,
uint32 l1Gas_,
bytes calldata data_
) external whenWithdrawalsEnabled onlySupportedL2Token(l2Token_) {
if(l2Token_ == l2TokenRebasable) {
uint256 shares = ERC20Rebasable(l2TokenRebasable).getSharesByTokens(amount_);
ERC20Rebasable(l2TokenRebasable).burnShares(msg.sender, shares);
_initiateWithdrawal(l1Token_, l2Token_, msg.sender, msg.sender, shares, l1Gas_, data_);
} else {
IERC20Bridged(l2TokenNonRebasable).bridgeBurn(msg.sender, amount_);
_initiateWithdrawal(l1Token_, l2Token_, msg.sender, msg.sender, amount_, l1Gas_, data_);
}
_withdrawTo(l2Token_, msg.sender, amount_, l1Gas_, data_);
}

/// @inheritdoc IL2ERC20Bridge
Expand All @@ -85,8 +75,28 @@ contract L2ERC20TokenBridge is
uint256 amount_,
uint32 l1Gas_,
bytes calldata data_
) external whenWithdrawalsEnabled onlySupportedL2Token(l2Token_) {
_initiateWithdrawal(l1TokenNonRebasable, l2Token_, msg.sender, to_, amount_, l1Gas_, data_);
) external whenWithdrawalsEnabled onlySupportedL2Token(l2Token_) {
_withdrawTo(l2Token_, to_, amount_, l1Gas_, data_);
}

function _withdrawTo(
address l2Token_,
address to_,
uint256 amount_,
uint32 l1Gas_,
bytes calldata data_
) internal {
if (l2Token_ == l2TokenRebasable) {

uint256 shares = ERC20Rebasable(l2TokenRebasable).getSharesByTokens(amount_);
ERC20Rebasable(l2TokenRebasable).burnShares(msg.sender, shares);
_initiateWithdrawal(l1TokenRebasable, l2TokenRebasable, msg.sender, to_, shares, l1Gas_, data_);

} else if (l2Token_ == l2TokenNonRebasable) {

IERC20Bridged(l2TokenNonRebasable).bridgeBurn(msg.sender, amount_);
_initiateWithdrawal(l2TokenNonRebasable, l2TokenNonRebasable, msg.sender, to_, amount_, l1Gas_, data_);
}
}

/// @inheritdoc IL2ERC20Bridge
Expand All @@ -112,6 +122,7 @@ contract L2ERC20TokenBridge is
} else if (isNonRebasableTokenFlow(l1Token_, l2Token_)) {
IERC20Bridged(l2TokenNonRebasable).bridgeMint(to_, amount_);
}

emit DepositFinalized(l1Token_, l2Token_, from_, to_, amount_, depositData.data);
}

Expand Down
1 change: 0 additions & 1 deletion contracts/optimism/interfaces/IL2ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ interface IL2ERC20Bridge {
/// solely as a convenience for external contracts. Aside from enforcing a maximum
/// length, these contracts provide no guarantees about its content.
function withdraw(
address l1Token_,
address l2Token_,
uint256 amount_,
uint32 l1Gas_,
Expand Down
3 changes: 1 addition & 2 deletions contracts/stubs/ERC20WrapableStub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ contract ERC20WrapableStub is IERC20Wrapable, ERC20 {

IERC20 public stETH;
address public bridge;
uint256 public tokensRate; /// wst/st
uint256 public tokensRate;

constructor(IERC20 stETH_, string memory name_, string memory symbol_)
ERC20(name_, symbol_)
{
stETH = stETH_;
console.log("constructor wrap stETH=",address(stETH));

tokensRate = 2 * 10 **18;
_mint(msg.sender, 1000000 * 10**18);
Expand Down
Loading

0 comments on commit 800e33f

Please sign in to comment.