runtimeverification / runtimeverification/kontrol

Align `prank` behavior to Foundry

Open
#190 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Python
Stars
122
Forks
16
PR merge metrics
No merged PRs in 30d

Description

Follow up to https://github.com/runtimeverification/kontrol/issues/120 and https://github.com/runtimeverification/kontrol/issues/110.
Related: https://github.com/runtimeverification/kontrol/issues/124.

Based on a Slack discussion with @hjorthjort and @anvacaru: in Foundry, prank is not effective when the test contract calls a function that is defined in a contract that the test is inherited from. With Foundry, all tests in the following contract pass:

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.6.2 <0.9.0;

import "forge-std/Test.sol";
import "forge-std/Vm.sol";
import "../src/timetravel/CallBreaker.sol";


contract PrankParent is Test {
  function parentFunction(address p) public {
    assertEq(p,msg.sender);
  }
}

contract External is Test {
  constructor(address p) {
    assertEq(p,msg.sender);
  }

  function externalFunction(address p) public {
    assertEq(p,msg.sender);
  }
}

contract PrankTest is PrankParent {

  function test_startP(address p) public {
    address sender = msg.sender;
    vm.startPrank(p);
    assertEq(msg.sender, sender);
    localFunc(sender);
    parentFunction(sender);
    External e = new External(p);
    e.externalFunction(p);
    vm.stopPrank();
  }

  function test_p(address p) public {
    vm.prank(p); External e = new External(p);
    address sender = msg.sender;
    vm.prank(p); assertEq(msg.sender, sender); e.externalFunction(p);
    vm.prank(p); localFunc(sender); e.externalFunction(p);
    vm.prank(p); parentFunction(sender); e.externalFunction(p);
    vm.prank(p); e.externalFunction(p);
  }


  function localFunc(address p) public {
    assertEq(p,msg.sender);
  }
}

In addition, vm.prank(x); vm.prank(x); causes a runtime failure in Foundry, while, in Kontrol, we insert a prank only if no other is active (source); this specific scenario is not handled, so the configuration would get stuck. We have a test for this here.

We should align prank-related behavior of Kontrol with Foundry.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the prank handling described in src/kontrol/kdist/foundry.md around lines 1266-1278, then read the existing scenario in src/tests/integration/test-data/foundry/test/PlainPrankTest.t.sol around lines 88-93. Review issues 120, 110, and 124 for related context. Done means Kontrol matches Foundry for inherited-function calls and repeated vm.prank calls, with integration coverage for the reported cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, solidity
Domain
blockchain, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.