An excellent assignment solution, and well-coded contract @Raf.PV7
You have included all of the additional functionality needed to solve the problem with the withdraw function.
The additional withdrawal event you’ve added is appropriate and well coded. The emit statement is in the correct position within the withdraw function, and it emits and logs relevant information when a call to the withdraw function has executed successfully.
You also have the other code in your withdraw function in the correct order to reduce security risk:
- check inputs (require statement)
- effects (update the contract state for reduction in balance)
- interactions (perform the transfer of funds from smart contract address to wallet address).
It’s important to modify the contract state:
balance[msg.sender] -= amount;
before actually transferring the funds out of the contract:
msg.sender.transfer(amount);
… just in case there is an attack after the transfer, but before the state is modified to reflect this operation. You’ll learn about the type of attack this prevents, and how it does it, in later courses. We wouldn’t expect you to know this at this early stage, though, so I’m just telling you for extra information, in case you haven’t already seen this explanation in some of the other posts in this discussion topic. Anyway, don’t worry about the details for now, although it’s good to be aware of, and it’s great that you’re already getting into good habits
Just one other observation…
The point of placing require statements within modifiers is for code reusability. This enables us to avoid code duplication and keeps our code concise. However, you cannot reuse either the withdrawValidations modifier or the transferValidations modifier elsewhere in your code, and it is unlikey you will be able to (if you develop your code further) due to each having a fairly specific use case. By having a separate modifer for both the withdraw and the transfer function, you have actually ended up with more code than you would by removing these 2 modifiers completely, and placing their require statements directly at the beginning of the corresponding function bodies.
However, you can avoid having to repeat the require statement which prevents a user withdrawing more ether than their current balance, by including just this require statement in one additional modifier. You can then include this modifier in both functions (as both require this particular input restriction) and place the other require statement within the only function that uses it. Have a go at making this modification.
Let us know if anything is unclear, or if you have any questions