---
description: >-
  Modify the above contract to include events for each deposit and withdrawal
  action. Test the contract to ensure that events are emitted correctly.
---

# E1: EthWallet.sol - Update

### Modifying EthWallet.sol

In this lesson the key differences to the contract are:&#x20;

* Gas optimized 'deposit' and 'withdraw' functions
* Events added for both functions.

```solidity
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/* errors */
error EthWallet__DepositMustBeAboveZero();
error EthWallet__WithdrawalMustBeAboveZero();
error EthWallet__WalletIsEmpty();
error EthWallet__WithdrawalExceedsUserBalance();
error EthWallet_InsufficientContractBalance();

// ----------------- Events added ---------------------

/* events */
event DepositSuccess(address depositer, uint amount);
event WithdrawSuccess(address withdrawer, uint amount);

// ----------------------------------------------------

contract EthWallet {
    /* structs */
    struct User {
        address ownerAddress;
        uint userBalance;
        uint withdrawnToday;
        uint lastWithdrawalTime;
    }

    /* mappings */
    mapping(address => User) private users;

    /* state variables */
    uint public constant dailyWithdrawalLimit = 10 ether;
    bool private locked;
    uint currentBalance;

    modifier withdrawalLimitCheck(uint _withdrawalAmount) {
        User storage currentUser = users[msg.sender];

        // Reset withdrawal amount if a new day has started
        if (isNewDay(currentUser.lastWithdrawalTime)) {
            currentUser.withdrawnToday = 0;
        }

        // Check if the requested withdrawal exceeds the daily limit
        require(
            currentUser.withdrawnToday + _withdrawalAmount <=
                dailyWithdrawalLimit,
            "Daily withdrawal limit exceeded"
        );

        // Update user's withdrawal data
        currentUser.withdrawnToday += _withdrawalAmount;
        currentUser.lastWithdrawalTime = block.timestamp;
        _;
    }

    modifier sufficientBalance(uint _withdrawalAmount) {
        uint withdrawalAmount = _withdrawalAmount;
        currentBalance = users[msg.sender].userBalance;
        if (currentBalance == 0) {
            revert EthWallet__WalletIsEmpty();
        } else if (_withdrawalAmount > address(this).balance) {
            revert EthWallet_InsufficientContractBalance();
        } else if (_withdrawalAmount > currentBalance) {
            revert EthWallet__WithdrawalExceedsUserBalance();
        }
        _;
    }

    modifier noReeentrant() {
        require(!locked, "No re_entrancy");
        locked = true;
        _;
        locked = false;
    }

    // Helper function to determine if a new day has started
    function isNewDay(uint lastWithdrawalTime) internal view returns (bool) {
        uint currentDay = block.timestamp / 1 days;
        uint lastWithdrawalDay = lastWithdrawalTime / 1 days;
        return currentDay > lastWithdrawalDay;
    }

    function deposit() public payable {
    
        // -Require statement replaced custom error for input validation-
        // ---------- 18.3% gas reduction for calculation cost ----------
        
        require(msg.value > 0, "Deposit must be above zero!");
        
        // --------------------------------------------------------------

        uint depositAmount = msg.value;

        if (users[msg.sender].userBalance > 0) {
            users[msg.sender].userBalance += depositAmount;
        } else {
            users[msg.sender] = User(msg.sender, depositAmount, 0, 0);
        }

        emit DepositSuccess(msg.sender, depositAmount);
    }

    function withdraw(
        uint _withdrawalAmount
    )
        external
        withdrawalLimitCheck(_withdrawalAmount)
        sufficientBalance(_withdrawalAmount)
        noReeentrant
    {
    
        // -Require statement replaced custom error for input validation-
        // ---------- 18.3% gas reduction for calculation cost ----------
        
        require(_withdrawalAmount > 0, "Withdrawal must be above zero!");
        
        // --------------------------------------------------------------

        uint withdrawalAmount = _withdrawalAmount;

        // Update user Balance
        users[msg.sender].userBalance -= withdrawalAmount;

        // Process withdrawal
        payable(msg.sender).transfer(withdrawalAmount);

        emit WithdrawSuccess(msg.sender, withdrawalAmount);
    }

    function getUserBalance() public view returns (uint) {
        if (users[msg.sender].ownerAddress != address(0)) {
            return users[msg.sender].userBalance;
        } else {
            return 0;
        }
    }
}
```
