Solidity Exercise - Distribute Transfer V2

Posted by Bourne's Blog - A Full-stack & Web3 Developer on May 13, 2024

Distribute Transfer V2

This exercise assumes you know how to sending Ether.

  • This contract has some ether in it, distribute it equally among the array of addresses that is passed as argument.
  • Write your code in the distributeEther function.
  • Consider scenarios where one of the recipients rejects the ether transfer, have a work around for that whereby other recipients still get their transfer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;
import "forge-std/console.sol" ;

contract DistributeV2 {
    /*
        This exercise assumes you know how to sending Ether.
        1. This contract has some ether in it, distribute it equally among the
           array of addresses that is passed as argument.
        2. Write your code in the `distributeEther` function.
        3. Consider scenarios where one of the recipients rejects the ether transfer, 
           have a work around for that whereby other recipients still get their transfer
    */

    constructor() payable {}

    function distributeEther(address[] memory addresses) public {
        // your code here
    }
}

Problem Analysis

The transfer to contracts which have not define receive and fallback function will revert. We’ll use low-level call to send the Eth, which will return a boolean value to indicate the transaction was success or failure.

Coding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;
import "forge-std/console.sol" ;

contract DistributeV2 {
    /*
        This exercise assumes you know how to sending Ether.
        1. This contract has some ether in it, distribute it equally among the
           array of addresses that is passed as argument.
        2. Write your code in the `distributeEther` function.
        3. Consider scenarios where one of the recipients rejects the ether transfer, 
           have a work around for that whereby other recipients still get their transfer
    */

    constructor() payable {}

    function distributeEther(address[] memory addresses) public {
        // your code here
        uint256 total = address(this).balance;
        uint256 amount = total / addresses.length;
        for (uint256 i=0; i < addresses.length; i++){
            (bool success, ) = addresses[i].call{value: amount}("");
            if (!success) {
                console.log("transfer failed to ", addresses[i]);
            }
        }
    }
}

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜  DistributeV2 git:(main) ✗ forge test -vvv
[⠊] Compiling...
[⠃] Compiling 19 files with Solc 0.8.25
[⠊] Solc 0.8.25 finished in 830.41ms
Compiler run successful!

Ran 1 test for test/DistributeV2.t.sol:DistributeV2Test
[PASS] testDistributeEther() (gas: 127820)
Logs:
  transfer failed to  0x2e234DAe75C793f67A35089C9d99245E1C58470b

Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.18ms (1.28ms CPU time)

Ran 1 test suite in 192.26ms (6.18ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)

Great, we passed the test!

Reference: Solidity Exercise - DistributeV2