forked from alexroan/forge-playground
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
251 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,14 @@ | ||
CounterTest:testIncrement() (gas: 28356) | ||
CounterTest:testSetNumber(uint256) (runs: 256, μ: 27020, ~: 28342) | ||
ModulusInvariants:invariantNumberIsLessThan20() (runs: 256, calls: 3840, reverts: 55) | ||
ModulusInvariants:testMod20() (gas: 28410) | ||
ModulusInvariants:testMod20(uint256) (runs: 256, μ: 26228, ~: 28483) | ||
ModulusTest:testMod20() (gas: 28387) | ||
ModulusTest:testMod20(uint256) (runs: 256, μ: 25862, ~: 28505) | ||
ModulusFuzz:test_mod_resultIsAlwaysLessThanModDivisor(uint256,uint256) (runs: 256, μ: 38396, ~: 40651) | ||
GAS_ModulusGas_ModAdmin:test_setModDivisor() (gas: 13812) | ||
GAS_ModulusGas_Owner:test_setModAdmin() (gas: 14155) | ||
GAS_ModulusGas_Stranger:test_getModDivisor() (gas: 7514) | ||
GAS_ModulusGas_Stranger:test_getOwner() (gas: 7577) | ||
GAS_ModulusGas_Stranger:test_getResult() (gas: 7546) | ||
GAS_ModulusGas_Stranger:test_mod() (gas: 12544) | ||
ModulusUnit:test_constructor() (gas: 10608) | ||
ModulusUnit:test_mod() (gas: 30677) | ||
ModulusUnit:test_mod_revertsIfModDivisorIsZero() (gas: 13544) | ||
ModulusUnit:test_setModAdmin() (gas: 15159) | ||
ModulusUnit:test_setModAdmin_onlyOwner_reverts() (gas: 11908) | ||
ModulusUnit:test_setModDivisor() (gas: 17945) | ||
ModulusUnit:test_setModDivisor_onlyModAdmin_reverts() (gas: 11895) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,71 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.13; | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.16; | ||
|
||
contract Modulus { | ||
uint256 public number; | ||
event ModAdminSet(address indexed previous, address indexed modAdmin); | ||
event ModDivisorSet(uint256 previous, uint256 modDivisor); | ||
event Result(uint256 n, uint256 modDivisor, uint256 result); | ||
|
||
function mod20(uint256 n) public { | ||
number = n % 20; | ||
error OnlyOwner(address expected, address actual); | ||
error OnlyModAdmin(address expected, address actual); | ||
|
||
/// @notice Owner of the contract - Can set the modAdmin | ||
address private s_owner; | ||
/// @notice modAdmin can set the mod value | ||
address private s_modAdmin; | ||
/// @notice modDivisor used in mod calculation | ||
uint256 private s_modDivisor; | ||
/// @notice result of the last mod calulation | ||
uint256 private s_result; | ||
|
||
constructor(address modAdmin) { | ||
s_owner = msg.sender; | ||
s_modAdmin = modAdmin; | ||
} | ||
|
||
function setModAdmin(address modAdmin) external onlyOwner() { | ||
address previous = s_modAdmin; | ||
s_modAdmin = modAdmin; | ||
emit ModAdminSet(previous, modAdmin); | ||
} | ||
|
||
function setModDivisor(uint256 modDivisor) external onlyModAdmin() { | ||
uint256 previous = s_modDivisor; | ||
s_modDivisor = modDivisor; | ||
emit ModDivisorSet(previous, modDivisor); | ||
} | ||
|
||
function mod(uint256 n) external { | ||
s_result = n % s_modDivisor; | ||
} | ||
|
||
function getOwner() external view returns (address owner) { | ||
owner = s_owner; | ||
} | ||
|
||
function getModAdmin() external view returns (address modAdmin) { | ||
modAdmin = s_modAdmin; | ||
} | ||
|
||
function getModDivisor() external view returns (uint256 modDivisor) { | ||
modDivisor = s_modDivisor; | ||
} | ||
|
||
function getResult() external view returns (uint256 result) { | ||
result = s_result; | ||
} | ||
|
||
modifier onlyOwner() { | ||
if (msg.sender != s_owner) { | ||
revert OnlyOwner(s_owner, msg.sender); | ||
} | ||
_; | ||
} | ||
|
||
modifier onlyModAdmin() { | ||
if (msg.sender != s_modAdmin) { | ||
revert OnlyModAdmin(s_modAdmin, msg.sender); | ||
} | ||
_; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.16; | ||
|
||
contract Constants { | ||
address internal constant OWNER = address(123); | ||
address internal constant MOD_ADMIN = address(124); | ||
address internal constant STRANGER = address(999); | ||
uint256 internal constant MOD_DIVISOR_1 = 20; | ||
uint256 internal constant MOD_DIVISOR_2 = 40; | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.16; | ||
|
||
import {Test} from "forge-std/Test.sol"; | ||
import {Modulus} from "../../src/Modulus.sol"; | ||
import {Constants} from "../Constants.t.sol"; | ||
|
||
contract ModulusFuzz is Test, Constants { | ||
Modulus internal s_modulus; | ||
|
||
function setUp() public virtual { | ||
changePrank(OWNER); | ||
s_modulus = new Modulus(MOD_ADMIN); | ||
changePrank(MOD_ADMIN); | ||
s_modulus.setModDivisor(MOD_DIVISOR_1); | ||
} | ||
|
||
function test_mod_resultIsAlwaysLessThanModDivisor(uint256 modDivisor, uint256 numerator) public { | ||
vm.assume(modDivisor > 0); | ||
s_modulus.setModDivisor(modDivisor); | ||
s_modulus.mod(numerator); | ||
assertLt(s_modulus.getResult(), modDivisor); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.16; | ||
|
||
import {Test} from "forge-std/Test.sol"; | ||
import {Modulus} from "../../src/Modulus.sol"; | ||
import {Constants} from "../Constants.t.sol"; | ||
|
||
/// @notice Prefixed with GAS_ so all raw gas costs are clumped together in .gas-snapshot | ||
contract GAS_Modulus_Base is Test, Constants { | ||
Modulus internal s_modulus; | ||
|
||
function setUp() public virtual { | ||
changePrank(OWNER); | ||
s_modulus = new Modulus(MOD_ADMIN); | ||
changePrank(MOD_ADMIN); | ||
s_modulus.setModDivisor(MOD_DIVISOR_1); | ||
changePrank(STRANGER); | ||
s_modulus.mod(1); | ||
} | ||
} | ||
|
||
contract GAS_ModulusGas_Owner is GAS_Modulus_Base { | ||
function setUp() public virtual override{ | ||
GAS_Modulus_Base.setUp(); | ||
changePrank(OWNER); | ||
} | ||
|
||
function test_setModAdmin() public { | ||
s_modulus.setModAdmin(STRANGER); | ||
} | ||
} | ||
|
||
contract GAS_ModulusGas_ModAdmin is GAS_Modulus_Base { | ||
function setUp() public virtual override { | ||
GAS_Modulus_Base.setUp(); | ||
changePrank(MOD_ADMIN); | ||
} | ||
|
||
function test_setModDivisor() public { | ||
s_modulus.setModDivisor(MOD_DIVISOR_2); | ||
} | ||
} | ||
|
||
contract GAS_ModulusGas_Stranger is GAS_Modulus_Base { | ||
function test_mod() public { | ||
s_modulus.mod(123); | ||
} | ||
|
||
function test_getOwner() public view { | ||
s_modulus.getOwner(); | ||
} | ||
|
||
function test_getModDivisor() public view { | ||
s_modulus.getModDivisor(); | ||
} | ||
|
||
function test_getResult() public view { | ||
s_modulus.getResult(); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.16; | ||
|
||
import {Test} from "forge-std/Test.sol"; | ||
import {Modulus} from "../../src/Modulus.sol"; | ||
import {Constants} from "../Constants.t.sol"; | ||
|
||
contract ModulusUnit is Test, Constants { | ||
Modulus internal s_modulus; | ||
|
||
function setUp() public virtual { | ||
changePrank(OWNER); | ||
s_modulus = new Modulus(MOD_ADMIN); | ||
changePrank(MOD_ADMIN); | ||
s_modulus.setModDivisor(MOD_DIVISOR_1); | ||
changePrank(OWNER); | ||
} | ||
|
||
// ========================================================================== | ||
// CONSTRUCTOR | ||
// ========================================================================== | ||
|
||
function test_constructor() public { | ||
assertEq(s_modulus.getOwner(), OWNER); | ||
assertEq(s_modulus.getModAdmin(), MOD_ADMIN); | ||
} | ||
|
||
// ========================================================================== | ||
// SET MOD ADMIN | ||
// ========================================================================== | ||
|
||
function test_setModAdmin_onlyOwner_reverts() public { | ||
changePrank(STRANGER); | ||
vm.expectRevert(abi.encodeWithSelector(Modulus.OnlyOwner.selector, OWNER, STRANGER)); | ||
s_modulus.setModAdmin(STRANGER); | ||
} | ||
|
||
function test_setModAdmin() public { | ||
s_modulus.setModAdmin(STRANGER); | ||
assertEq(s_modulus.getModAdmin(), STRANGER); | ||
} | ||
|
||
// ========================================================================== | ||
// SET MOD DIVISOR | ||
// ========================================================================== | ||
|
||
function test_setModDivisor_onlyModAdmin_reverts() public { | ||
changePrank(STRANGER); | ||
vm.expectRevert(abi.encodeWithSelector(Modulus.OnlyModAdmin.selector, MOD_ADMIN, STRANGER)); | ||
s_modulus.setModDivisor(123); | ||
} | ||
|
||
function test_setModDivisor() public { | ||
changePrank(MOD_ADMIN); | ||
s_modulus.setModDivisor(MOD_DIVISOR_2); | ||
assertEq(s_modulus.getModDivisor(), MOD_DIVISOR_2); | ||
} | ||
|
||
// ========================================================================== | ||
// MOD | ||
// ========================================================================== | ||
|
||
function test_mod() public { | ||
uint256 numerator = 50; | ||
uint256 expected = numerator % MOD_DIVISOR_1; | ||
|
||
s_modulus.mod(numerator); | ||
assertEq(s_modulus.getResult(), expected); | ||
} | ||
|
||
function test_mod_revertsIfModDivisorIsZero() public { | ||
changePrank(MOD_ADMIN); | ||
s_modulus.setModDivisor(0); | ||
vm.expectRevert(); | ||
s_modulus.mod(50); | ||
} | ||
} |