-
Notifications
You must be signed in to change notification settings - Fork 0
LGE Staking #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: ozean
Are you sure you want to change the base?
LGE Staking #8
Conversation
| constructor( | ||
| address _owner, | ||
| address _stETH, | ||
| address _wstETH, | ||
| address[] memory _tokens, | ||
| uint256[] memory _depositCaps | ||
| ) { | ||
| _transferOwnership(_owner); | ||
| stETH = _stETH; | ||
| wstETH = _wstETH; | ||
| IstETH(stETH).approve(wstETH, ~uint256(0)); | ||
| uint256 length = _tokens.length; | ||
| require( | ||
| length == _depositCaps.length, "LGE Staking: Tokens array length must equal the Deposit Caps array length." | ||
| ); | ||
| for (uint256 i; i < length; ++i) { | ||
| allowlisted[_tokens[i]] = true; | ||
| emit AllowlistSet(_tokens[i], true); | ||
| depositCap[_tokens[i]] = _depositCaps[i]; | ||
| emit DepositCapSet(_tokens[i], _depositCaps[i]); | ||
| } | ||
| } |
Check warning
Code scanning / Slither
Unused return Medium
| function migrate(address _l2Destination, address[] calldata _tokens) external nonReentrant whenNotPaused { | ||
| require(migrationActivated(), "LGE Staking: Migration not active."); | ||
| require(_l2Destination != address(0), "LGE Staking: May not send tokens to the zero address."); | ||
| uint256 length = _tokens.length; | ||
| require(length > 0, "LGE Staking: Must migrate some tokens."); | ||
| uint256[] memory amounts = new uint256[](length); | ||
| uint256 amount; | ||
| for (uint256 i; i < length; i++) { | ||
| amount = balance[_tokens[i]][msg.sender]; | ||
| require(amount > 0, "LGE Staking: No tokens to migrate."); | ||
| balance[_tokens[i]][msg.sender] -= amount; | ||
| totalDeposited[_tokens[i]] -= amount; | ||
| amounts[i] = amount; | ||
| IERC20(_tokens[i]).safeTransfer(address(lgeMigration), amount); | ||
| } | ||
| lgeMigration.migrate(_l2Destination, _tokens, amounts); | ||
| emit TokensMigrated(msg.sender, _l2Destination, _tokens, amounts); | ||
| } |
Check warning
Code scanning / Slither
Reentrancy vulnerabilities Medium
External calls:
- IERC20(_tokens[i]).safeTransfer(address(lgeMigration),amount)
State variables written after the call(s):
- balance[_tokens[i]][msg.sender] -= amount
LGEStaking.balance can be used in cross function reentrancies:
- LGEStaking.balance
- totalDeposited[_tokens[i]] -= amount
LGEStaking.totalDeposited can be used in cross function reentrancies:
- LGEStaking.totalDeposited
| function depositETH() external payable nonReentrant whenNotPaused { | ||
| require(!migrationActivated(), "LGE Staking: May not deposit once migration has been activated."); | ||
| require(msg.value > 0, "LGE Staking: May not deposit nothing."); | ||
| require(allowlisted[wstETH], "LGE Staking: Token must be allowlisted."); | ||
| IstETH(stETH).submit{value: msg.value}(address(0)); | ||
| uint256 wstETHAmount = IwstETH(wstETH).wrap(IstETH(stETH).balanceOf(address(this))); | ||
| require( | ||
| totalDeposited[wstETH] + wstETHAmount < depositCap[wstETH], | ||
| "LGE Staking: deposit amount exceeds deposit cap." | ||
| ); | ||
| balance[wstETH][msg.sender] += wstETHAmount; | ||
| totalDeposited[wstETH] += wstETHAmount; | ||
| emit Deposit(wstETH, wstETHAmount, msg.sender); | ||
| } |
Check warning
Code scanning / Slither
Unused return Medium
| function depositERC20(address _token, uint256 _amount) external nonReentrant whenNotPaused { | ||
| require(!migrationActivated(), "LGE Staking: May not deposit once migration has been activated."); | ||
| require(_amount > 0, "LGE Staking: May not deposit nothing."); | ||
| require(allowlisted[_token], "LGE Staking: Token must be allowlisted."); | ||
| require( | ||
| totalDeposited[_token] + _amount < depositCap[_token], "LGE Staking: deposit amount exceeds deposit cap." | ||
| ); | ||
| uint256 balanceBefore = IERC20(_token).balanceOf(address(this)); | ||
| IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount); | ||
| require( | ||
| IERC20(_token).balanceOf(address(this)) - balanceBefore == _amount, | ||
| "LGE Staking: Fee-on-transfer tokens not supported." | ||
| ); | ||
| balance[_token][msg.sender] += _amount; | ||
| totalDeposited[_token] += _amount; | ||
| emit Deposit(_token, _amount, msg.sender); | ||
| } |
Check warning
Code scanning / Slither
Reentrancy vulnerabilities Medium
External calls:
- IERC20(_token).safeTransferFrom(msg.sender,address(this),_amount)
State variables written after the call(s):
- totalDeposited[_token] += _amount
LGEStaking.totalDeposited can be used in cross function reentrancies:
- LGEStaking.totalDeposited
| /// @notice This function allows the owner to modify the deposit cap for deposited tokens. | ||
| /// @param _token The token address to modify the deposit cap. | ||
| /// @param _newDepositCap The new deposit cap. | ||
| function setDepositCap(address _token, uint256 _newDepositCap) external onlyOwner { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to ensure _newDepositCap is validated to ensure it has realistic values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's necessary. Suppose an unrealistic value is set, a second transaction can be made to correct it.
| /// @dev The new migration contract must conform to the ILGEMigration interface. | ||
| /// @dev If this contract is set to address(0) migration is deactivated | ||
| function setMigrationContract(address _contract) external onlyOwner { | ||
| lgeMigration = ILGEMigration(_contract); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if lgeMigration is set to malicious contract then users calling "migrate" will be transferred to it.
Need to ensure Owner control is set to multisig
| } else if (_tokens[i] == wstETH) { | ||
| /// Handle wstETH | ||
| IERC20(_tokens[i]).safeApprove(address(l1LidoTokensBridge), _amounts[i]); | ||
| l1LidoTokensBridge.depositERC20To( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given we are planning to support Hyperlane Warp routes for wstETH, do we want to keep the lido token bridge here for migrating wstETH?
Hyperlane could support wstETH as ERC20.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, this needs to change given the bridging solution per asset we decide for Ozean.
| } else { | ||
| /// Handle other tokens | ||
| IERC20(_tokens[i]).safeApprove(address(l1StandardBridge), _amounts[i]); | ||
| l1StandardBridge.depositERC20To( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Hyperlane bridge have the same interface 'bridge.depositERC20To()or we are going to usel1standardBridge` for the LGE migration ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hyperlane have their own contract interface, the migration contract will need to be updated given the bridging solution per asset we decide for Ozean.
jacko125
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@0xCooki Reviewed some comments about the Migration contract and LGE
LGE
LGE Migration
OzUSD