Skip to content
This repository was archived by the owner on Jan 4, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ leads. The leads can choose to update this value themselves.

| Contract | Address | Version |
| -------- | ------- | ------- |
| `PactFactory` | [0x0bc342e7bbf737ba123b1167e528a28cebb8b679](https://optimistic.etherscan.io/address/0x0bc342e7bbf737ba123b1167e528a28cebb8b679) | `0.3.0` |
| `Pact` (implementation) | [0x60d1a1755065e4cac8777248c2878c847c9a5dd5](https://optimistic.etherscan.io/address/0x60d1a1755065e4cac8777248c2878c847c9a5dd5) | `0.3.0` |
| `PactFactory` | [0x642a7864cBe44ED24D408Cbc38117Cfd6E6D1a95](https://optimistic.etherscan.io/address/0x642a7864cBe44ED24D408Cbc38117Cfd6E6D1a95) | `0.2.0` |
| `Pact` (implementation) | [0x4eE4ff6D24c8D334fA41b560Dac95BB3CEF828a1](https://optimistic.etherscan.io/address/0x4eE4ff6D24c8D334fA41b560Dac95BB3CEF828a1) | `0.2.0` |

Expand Down
13 changes: 11 additions & 2 deletions src/Pact.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { SafeCall } from "./SafeCall.sol";
/// It is expected that the pre-agreed upon commitment is observed. The rule of law
/// dictates meatspace.
contract Pact is Clone {
string constant public version = "0.2.0";
string constant public version = "0.3.0";

/// @notice Used to determine if the pact has been initialized.
bool internal _initialized;
Expand Down Expand Up @@ -68,6 +68,9 @@ contract Pact is Clone {
/// @notice Error when trying to resolve the Pact too early.
error Early();

/// @notice Error when putting too much value into the Pact.
error Overflow();

/// @notice Error when trying to `initialize()` when the Pact has
/// already been initialized.
error Initialized();
Expand All @@ -90,6 +93,7 @@ contract Pact is Clone {
/// so that ether can be returned in case not enough capital is accumulated.
fallback() external payable {
if (resolved) revert Resolved();
if (address(this).balance > sum()) revert Overflow();

address sender = msg.sender;
uint256 value = msg.value;
Expand Down Expand Up @@ -119,7 +123,12 @@ contract Pact is Clone {
return duration() + start;
}

/// @notice
/// @notice Convenience getter for the balance in the Pact.
function balance() public view returns (uint256) {
return address(this).balance;
}

/// @notice Useful for ensuring that the agreement matches the commitment.
function check(string memory _agreement) public pure returns (bool) {
return keccak256(bytes(_agreement)) == commitment();
}
Expand Down
24 changes: 24 additions & 0 deletions test/MutualAssuranceContract.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -278,4 +278,28 @@ contract MutualAssuranceContractTest is Test {
uint256 alicePostBalance = alice.balance;
assertEq(alicePostBalance, alicePreBalance);
}

/// @notice Only allow the Pact to accept the exact amount of ether. This creates a race
/// condition.
function test_pact_overflow() external {
Pact pact = _deploy();

uint256 value = pact.sum() - 1;

vm.expectEmit(true, true, true, true, address(pact));
emit Assurance(alice, value);

vm.prank(alice);
(bool success, ) = address(pact).call{ value: value }(hex"");
assertTrue(success);

vm.expectRevert(abi.encodeWithSelector(Pact.Overflow.selector));
address(pact).call{ value: 2 }(hex"");

vm.expectEmit(true, true, true, true, address(pact));
emit Assurance(alice, 1);

vm.prank(alice);
(success, ) = address(pact).call{ value: 1 }(hex"");
}
}