Authentication

Testing authentication in Foundry

The target is a wallet contract Wallet.sol:

pragma solidity ^0.8.18;

contract Wallet {
    address payable public owner;

    constructor() payable {
        owner = payable(msg.sender);
    }

    receive() external payable {}

    function withdraw(uint256 _amount) external {
        require(msg.sender == owner, "caller is not owner");
        payable(msg.sender).transfer(_amount);
    }

    function setOwner(address _owner) external {
        require(msg.sender == owner, "caller is not owner");
        owner = payable(_owner);
    }
}

Create a test file Auth.t.sol:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.18;

import "forge-std/Test.sol";
import {Wallet} from "../src/Wallet.sol";

contract AuthTest is Test {
    Wallet public wallet;

    function setUp() public {
        wallet = new Wallet();
    }

    function testSetOwner() public {
        wallet.setOwner(address(1));
        assertEq(wallet.owner(), address(1));
    }
}

This AuthTest contract can call wallet.setOwner() because it was set as the owner in the constructor.

Write a fail test case:

function testFailNotOwner() public {
    vm.prank(address(1));
    wallet.setOwner(address(1));
    assertEq(wallet.owner(), address(1));
}

vm.prank(address(1)) means "for the next call, pretend we are address(1)". This test case would fail because address(1) is not the owner so that it cannot call wallet.setOwner().

An extension of vm.prank() is the vm.startPrank() and vm.endPrank() pair. The impersonation will start on vm.startPrank() until vm.endPrank() is executed.

function testFailSetOwnerAgain() public {
    // msg.sender = address(this)
    wallet.setOwner(address(1));

    vm.startPrank(address(1));

    // msg.sender = address(1)
    wallet.setOwner(address(1));
    wallet.setOwner(address(1));
    wallet.setOwner(address(1));

    vm.stopPrank();

    // msg.sender = address(this) -> revert because address(this) is not the owner anymore
    wallet.setOwner(address(1));
}

Last updated