Nice solution @kasunkv
Your inheritance structure is well coded, and youâve met all of the assignment objectives
Your implementation of a multi-level inheritance structure is the best approach, because it is more streamlined. Bank only needs to explicitly inherit Destroyable because it will implicitly inherit Ownable via Destroyable.
Youâve also added some well-coded additional functionality:
- OwnershipSet event, and corresponding emit statement in the constructor.
- getContractBalance function. When testing the contract, itâs very useful to be able to check the total contract balance as well as individual user balances.
In fact, after calling your transfer() function, you can use your two getter functions to check 3 balances: (i) the total contract balance (ii) the senderâs individual balance in the mapping, and (iii) the recipientâs individual balance in the mapping. If the transfer() function was working correctly, the total contract balance would equal the sum of all of the individual user balances. However, with your current code, yours wonât, as a result of the issue I raised in my feedback for your Transfer Assignment solution.
This is actually a serious vulnerability, because the recipients of transfers will not only receive the ether in their external accounts, but their entitlement to withdraw ether from the contract (determined by their individual balances in the mapping) will also be overstated by equivalent amounts. This means these users will potentially be able to withdraw more ether from the contract (either to their own external address, or as a transfer to any other external address of their choice) than rightfully belongs to them, which effectively amounts to stealing other usersâ funds.
You will see from my other feedback that this is easily fixed.
Let me know if you have any questions.