Skip to content

Commit

Permalink
Merge pull request #659 from lidofinance/fix/shapella-upgrade-fixes
Browse files Browse the repository at this point in the history
Fix: shapella upgrade fixes [WIP]
  • Loading branch information
TheDZhon authored Mar 13, 2023
2 parents b609306 + 4ec32dc commit 2bce10d
Show file tree
Hide file tree
Showing 140 changed files with 10,951 additions and 3,756 deletions.
5 changes: 4 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

RED_COLOR='\033[0;31m'
NO_COLOR='\033[0m'

yarn compile
git diff --quiet lib/abi
git diff --quiet lib/abi || (echo -e "${RED_COLOR}Unstaged ABIs detected${NO_COLOR}"; exit 1)

yarn lint
253 changes: 114 additions & 139 deletions contracts/0.4.24/Lido.sol

Large diffs are not rendered by default.

34 changes: 20 additions & 14 deletions contracts/0.4.24/StETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ contract StETH is IERC20, Pausable {
* For reference types, conventional storage variables are used since it's non-trivial
* and error-prone to implement reference-type unstructured storage using Solidity v0.4;
* see https://github.com/lidofinance/lido-dao/issues/181#issuecomment-736098834
*
* keccak256("lido.StETH.totalShares")
*/
bytes32 internal constant TOTAL_SHARES_POSITION = keccak256("lido.StETH.totalShares");
bytes32 internal constant TOTAL_SHARES_POSITION =
0xe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e;

/**
* @notice An executed shares transfer from `sender` to `recipient`.
Expand Down Expand Up @@ -232,7 +235,7 @@ contract StETH is IERC20, Pausable {
*/
function transferFrom(address _sender, address _recipient, uint256 _amount) external returns (bool) {
uint256 currentAllowance = allowances[_sender][msg.sender];
require(currentAllowance >= _amount, "TRANSFER_AMOUNT_EXCEEDS_ALLOWANCE");
require(currentAllowance >= _amount, "ALLOWANCE_EXCEEDED");

_transfer(_sender, _recipient, _amount);
_approve(_sender, msg.sender, currentAllowance.sub(_amount));
Expand Down Expand Up @@ -271,7 +274,7 @@ contract StETH is IERC20, Pausable {
*/
function decreaseAllowance(address _spender, uint256 _subtractedValue) external returns (bool) {
uint256 currentAllowance = allowances[msg.sender][_spender];
require(currentAllowance >= _subtractedValue, "DECREASED_ALLOWANCE_BELOW_ZERO");
require(currentAllowance >= _subtractedValue, "ALLOWANCE_BELOW_ZERO");
_approve(msg.sender, _spender, currentAllowance.sub(_subtractedValue));
return true;
}
Expand Down Expand Up @@ -355,7 +358,7 @@ contract StETH is IERC20, Pausable {
) external returns (uint256) {
uint256 currentAllowance = allowances[_sender][msg.sender];
uint256 tokensAmount = getPooledEthByShares(_sharesAmount);
require(currentAllowance >= tokensAmount, "TRANSFER_AMOUNT_EXCEEDS_ALLOWANCE");
require(currentAllowance >= tokensAmount, "ALLOWANCE_EXCEEDED");

_transferShares(_sender, _recipient, _sharesAmount);
_approve(_sender, msg.sender, currentAllowance.sub(tokensAmount));
Expand Down Expand Up @@ -396,8 +399,8 @@ contract StETH is IERC20, Pausable {
* - `_spender` cannot be the zero address.
*/
function _approve(address _owner, address _spender, uint256 _amount) internal {
require(_owner != address(0), "APPROVE_FROM_ZERO_ADDRESS");
require(_spender != address(0), "APPROVE_TO_ZERO_ADDRESS");
require(_owner != address(0), "APPROVE_FROM_ZERO_ADDR");
require(_spender != address(0), "APPROVE_TO_ZERO_ADDR");

allowances[_owner][_spender] = _amount;
emit Approval(_owner, _spender, _amount);
Expand All @@ -423,17 +426,18 @@ contract StETH is IERC20, Pausable {
* Requirements:
*
* - `_sender` cannot be the zero address.
* - `_recipient` cannot be the zero address.
* - `_recipient` cannot be the zero address or the `stETH` token contract itself
* - `_sender` must hold at least `_sharesAmount` shares.
* - the contract must not be paused.
*/
function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal {
require(_sender != address(0), "TRANSFER_FROM_THE_ZERO_ADDRESS");
require(_recipient != address(0), "TRANSFER_TO_THE_ZERO_ADDRESS");
require(_sender != address(0), "TRANSFER_FROM_ZERO_ADDR");
require(_recipient != address(0), "TRANSFER_TO_ZERO_ADDR");
require(_recipient != address(this), "TRANSFER_TO_STETH_CONTRACT");
_whenNotStopped();

uint256 currentSenderShares = shares[_sender];
require(_sharesAmount <= currentSenderShares, "TRANSFER_AMOUNT_EXCEEDS_BALANCE");
require(_sharesAmount <= currentSenderShares, "BALANCE_EXCEEDED");

shares[_sender] = currentSenderShares.sub(_sharesAmount);
shares[_recipient] = shares[_recipient].add(_sharesAmount);
Expand All @@ -451,7 +455,7 @@ contract StETH is IERC20, Pausable {
* - the contract must not be paused.
*/
function _mintShares(address _recipient, uint256 _sharesAmount) internal returns (uint256 newTotalShares) {
require(_recipient != address(0), "MINT_TO_THE_ZERO_ADDRESS");
require(_recipient != address(0), "MINT_TO_ZERO_ADDR");

newTotalShares = _getTotalShares().add(_sharesAmount);
TOTAL_SHARES_POSITION.setStorageUint256(newTotalShares);
Expand All @@ -477,10 +481,10 @@ contract StETH is IERC20, Pausable {
* - the contract must not be paused.
*/
function _burnShares(address _account, uint256 _sharesAmount) internal returns (uint256 newTotalShares) {
require(_account != address(0), "BURN_FROM_THE_ZERO_ADDRESS");
require(_account != address(0), "BURN_FROM_ZERO_ADDR");

uint256 accountShares = shares[_account];
require(_sharesAmount <= accountShares, "BURN_AMOUNT_EXCEEDS_BALANCE");
require(_sharesAmount <= accountShares, "BALANCE_EXCEEDED");

uint256 preRebaseTokenAmount = getPooledEthByShares(_sharesAmount);

Expand Down Expand Up @@ -509,11 +513,13 @@ contract StETH is IERC20, Pausable {
* Allows to get rid of zero checks for `totalShares` and `totalPooledEther`
* and overcome corner cases.
*
* NB: reverts if the current contract's balance is zero.
*
* @dev must be invoked before using the token
*/
function _bootstrapInitialHolder() internal returns (uint256) {
uint256 balance = address(this).balance;
require(balance != 0, "EMPTY_INIT_BALANCE");
assert(balance != 0);

if (_getTotalShares() == 0) {
// if protocol is empty bootstrap it with the contract's balance
Expand Down
21 changes: 12 additions & 9 deletions contracts/0.4.24/StETHPermit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pragma solidity 0.4.24;

import {UnstructuredStorage} from "@aragon/os/contracts/common/UnstructuredStorage.sol";

import {ECDSA} from "../common/lib/ECDSA.sol";
import {SignatureUtils} from "../common/lib/SignatureUtils.sol";
import {IEIP712StETH} from "../common/interfaces/IEIP712StETH.sol";

import {StETH} from "./StETH.sol";
Expand Down Expand Up @@ -69,14 +69,19 @@ contract StETHPermit is IERC2612, StETH {

/**
* @dev Storage position used for the EIP712 message utils contract
*
* keccak256("lido.StETHPermit.eip712StETH")
*/
bytes32 internal constant EIP712_STETH_POSITION = keccak256("lido.StETHPermit.eip712StETH");
bytes32 internal constant EIP712_STETH_POSITION =
0x42b2d95e1ce15ce63bf9a8d9f6312cf44b23415c977ffa3b884333422af8941c;

/**
* @dev Typehash constant for ERC-2612 (Permit)
*
* keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
*/
bytes32 internal constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;

/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
Expand All @@ -94,17 +99,15 @@ contract StETHPermit is IERC2612, StETH {
function permit(
address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s
) external {
require(block.timestamp <= _deadline, "ERC20Permit: expired deadline");
require(block.timestamp <= _deadline, "DEADLINE_EXPIRED");

bytes32 structHash = keccak256(
abi.encode(PERMIT_TYPEHASH, _owner, _spender, _value, _useNonce(_owner), _deadline)
);

bytes32 hash = IEIP712StETH(getEIP712StETH()).hashTypedDataV4(address(this), structHash);

address signer = ECDSA.recover(hash, _v, _r, _s);
require(signer == _owner, "ERC20Permit: invalid signature");

require(SignatureUtils.isValidSignature(_owner, hash, _v, _r, _s), "INVALID_SIGNATURE");
_approve(_owner, _spender, _value);
}

Expand Down Expand Up @@ -158,8 +161,8 @@ contract StETHPermit is IERC2612, StETH {
* @dev Initialize EIP712 message utils contract for stETH
*/
function _initializeEIP712StETH(address _eip712StETH) internal {
require(_eip712StETH != address(0), "StETHPermit: zero eip712StETH");
require(getEIP712StETH() == address(0), "StETHPermit: eip712StETH already set");
require(_eip712StETH != address(0), "ZERO_EIP712STETH");
require(getEIP712StETH() == address(0), "EIP712STETH_ALREADY_SET");

EIP712_STETH_POSITION.setStorageAddress(_eip712StETH);

Expand Down
Loading

0 comments on commit 2bce10d

Please sign in to comment.