@@ -79,8 +79,11 @@ contract StETH is IERC20, Pausable {
79
79
* For reference types, conventional storage variables are used since it's non-trivial
80
80
* and error-prone to implement reference-type unstructured storage using Solidity v0.4;
81
81
* see https://github.com/lidofinance/lido-dao/issues/181#issuecomment-736098834
82
+ *
83
+ * keccak256("lido.StETH.totalShares")
82
84
*/
83
- bytes32 internal constant TOTAL_SHARES_POSITION = keccak256 ("lido.StETH.totalShares " );
85
+ bytes32 internal constant TOTAL_SHARES_POSITION =
86
+ 0xe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e ;
84
87
85
88
/**
86
89
* @notice An executed shares transfer from `sender` to `recipient`.
@@ -232,7 +235,7 @@ contract StETH is IERC20, Pausable {
232
235
*/
233
236
function transferFrom (address _sender , address _recipient , uint256 _amount ) external returns (bool ) {
234
237
uint256 currentAllowance = allowances[_sender][msg .sender ];
235
- require (currentAllowance >= _amount, "TRANSFER_AMOUNT_EXCEEDS_ALLOWANCE " );
238
+ require (currentAllowance >= _amount, "ALLOWANCE_EXCEEDED " );
236
239
237
240
_transfer (_sender, _recipient, _amount);
238
241
_approve (_sender, msg .sender , currentAllowance.sub (_amount));
@@ -271,7 +274,7 @@ contract StETH is IERC20, Pausable {
271
274
*/
272
275
function decreaseAllowance (address _spender , uint256 _subtractedValue ) external returns (bool ) {
273
276
uint256 currentAllowance = allowances[msg .sender ][_spender];
274
- require (currentAllowance >= _subtractedValue, "DECREASED_ALLOWANCE_BELOW_ZERO " );
277
+ require (currentAllowance >= _subtractedValue, "ALLOWANCE_BELOW_ZERO " );
275
278
_approve (msg .sender , _spender, currentAllowance.sub (_subtractedValue));
276
279
return true ;
277
280
}
@@ -355,7 +358,7 @@ contract StETH is IERC20, Pausable {
355
358
) external returns (uint256 ) {
356
359
uint256 currentAllowance = allowances[_sender][msg .sender ];
357
360
uint256 tokensAmount = getPooledEthByShares (_sharesAmount);
358
- require (currentAllowance >= tokensAmount, "TRANSFER_AMOUNT_EXCEEDS_ALLOWANCE " );
361
+ require (currentAllowance >= tokensAmount, "ALLOWANCE_EXCEEDED " );
359
362
360
363
_transferShares (_sender, _recipient, _sharesAmount);
361
364
_approve (_sender, msg .sender , currentAllowance.sub (tokensAmount));
@@ -396,8 +399,8 @@ contract StETH is IERC20, Pausable {
396
399
* - `_spender` cannot be the zero address.
397
400
*/
398
401
function _approve (address _owner , address _spender , uint256 _amount ) internal {
399
- require (_owner != address (0 ), "APPROVE_FROM_ZERO_ADDRESS " );
400
- require (_spender != address (0 ), "APPROVE_TO_ZERO_ADDRESS " );
402
+ require (_owner != address (0 ), "APPROVE_FROM_ZERO_ADDR " );
403
+ require (_spender != address (0 ), "APPROVE_TO_ZERO_ADDR " );
401
404
402
405
allowances[_owner][_spender] = _amount;
403
406
emit Approval (_owner, _spender, _amount);
@@ -423,17 +426,18 @@ contract StETH is IERC20, Pausable {
423
426
* Requirements:
424
427
*
425
428
* - `_sender` cannot be the zero address.
426
- * - `_recipient` cannot be the zero address.
429
+ * - `_recipient` cannot be the zero address or the `stETH` token contract itself
427
430
* - `_sender` must hold at least `_sharesAmount` shares.
428
431
* - the contract must not be paused.
429
432
*/
430
433
function _transferShares (address _sender , address _recipient , uint256 _sharesAmount ) internal {
431
- require (_sender != address (0 ), "TRANSFER_FROM_THE_ZERO_ADDRESS " );
432
- require (_recipient != address (0 ), "TRANSFER_TO_THE_ZERO_ADDRESS " );
434
+ require (_sender != address (0 ), "TRANSFER_FROM_ZERO_ADDR " );
435
+ require (_recipient != address (0 ), "TRANSFER_TO_ZERO_ADDR " );
436
+ require (_recipient != address (this ), "TRANSFER_TO_STETH_CONTRACT " );
433
437
_whenNotStopped ();
434
438
435
439
uint256 currentSenderShares = shares[_sender];
436
- require (_sharesAmount <= currentSenderShares, "TRANSFER_AMOUNT_EXCEEDS_BALANCE " );
440
+ require (_sharesAmount <= currentSenderShares, "BALANCE_EXCEEDED " );
437
441
438
442
shares[_sender] = currentSenderShares.sub (_sharesAmount);
439
443
shares[_recipient] = shares[_recipient].add (_sharesAmount);
@@ -451,7 +455,7 @@ contract StETH is IERC20, Pausable {
451
455
* - the contract must not be paused.
452
456
*/
453
457
function _mintShares (address _recipient , uint256 _sharesAmount ) internal returns (uint256 newTotalShares ) {
454
- require (_recipient != address (0 ), "MINT_TO_THE_ZERO_ADDRESS " );
458
+ require (_recipient != address (0 ), "MINT_TO_ZERO_ADDR " );
455
459
456
460
newTotalShares = _getTotalShares ().add (_sharesAmount);
457
461
TOTAL_SHARES_POSITION.setStorageUint256 (newTotalShares);
@@ -477,10 +481,10 @@ contract StETH is IERC20, Pausable {
477
481
* - the contract must not be paused.
478
482
*/
479
483
function _burnShares (address _account , uint256 _sharesAmount ) internal returns (uint256 newTotalShares ) {
480
- require (_account != address (0 ), "BURN_FROM_THE_ZERO_ADDRESS " );
484
+ require (_account != address (0 ), "BURN_FROM_ZERO_ADDR " );
481
485
482
486
uint256 accountShares = shares[_account];
483
- require (_sharesAmount <= accountShares, "BURN_AMOUNT_EXCEEDS_BALANCE " );
487
+ require (_sharesAmount <= accountShares, "BALANCE_EXCEEDED " );
484
488
485
489
uint256 preRebaseTokenAmount = getPooledEthByShares (_sharesAmount);
486
490
@@ -509,11 +513,13 @@ contract StETH is IERC20, Pausable {
509
513
* Allows to get rid of zero checks for `totalShares` and `totalPooledEther`
510
514
* and overcome corner cases.
511
515
*
516
+ * NB: reverts if the current contract's balance is zero.
517
+ *
512
518
* @dev must be invoked before using the token
513
519
*/
514
520
function _bootstrapInitialHolder () internal returns (uint256 ) {
515
521
uint256 balance = address (this ).balance;
516
- require (balance != 0 , " EMPTY_INIT_BALANCE " );
522
+ assert (balance != 0 );
517
523
518
524
if (_getTotalShares () == 0 ) {
519
525
// if protocol is empty bootstrap it with the contract's balance
0 commit comments