Skip to content

Commit

Permalink
402 create contract for storing mapping marketid listipfshashes for p…
Browse files Browse the repository at this point in the history
…redictions (#7)

* Added agent result mappings v0

* Adapted contract/test to have multiple IPFS hashes per market

* Final version of contract, ready for deployment

* Removed verbose comments | Improved README

* Refactored mapping to include publisher address

* Update src/OmenAgentResultMapping.sol

Co-authored-by: Peter Jung <[email protected]>

* Update src/OmenAgentResultMapping.sol

Co-authored-by: Peter Jung <[email protected]>

* Addressed PR comments

* Removing index on emitted event

* Update src/OmenAgentResultMapping.sol

Co-authored-by: Peter Jung <[email protected]>

* Added Probability to struct and event

* Improved comments and naming

* Imported event from contract directly

* Initialize subgraph

* Initialize subgraph

* Revert "Initialize subgraph"

This reverts commit f481b28.

* Revert "Initialize subgraph"

This reverts commit 8b4e5a4.

---------

Co-authored-by: Peter Jung <[email protected]>
  • Loading branch information
gabrielfior and kongzii authored Sep 20, 2024
1 parent efcaee5 commit cfe4296
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ forge create --gas-limit 10000000 --rpc-url https://rpc.chiadochain.net --priva
ETHERSCAN_API_KEY=<your_api_key> forge create --verify --verifier-url https://api.gnosisscan.io/api --rpc-url https://gnosis-rpc.publicnode.com --private-key <your_private_key> OmenThumbnailMapping
```

#### (Optional) Deploy on a Tenderly testnet
forge create OmenAgentResultMapping \
--private-key <private_key> \
--rpc-url <tenderly_rpc_url> \
--etherscan-api-key <tenderly-access-token> \
--verify \
--verifier-url <tenderly_roc_url>/verify/etherscan


### Cast

```shell
Expand Down
35 changes: 35 additions & 0 deletions src/OmenAgentResultMapping.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

import {Prediction} from "./structs.sol";

contract OmenAgentResultMapping {
event PredictionAdded(
address indexed marketAddress,
uint16 estimatedProbabilityBps,
address indexed publisherAddress,
bytes32 txHash,
bytes32 ipfsHash
);

mapping(address => Prediction[]) private marketPredictions;

constructor() {}

function getPredictions(address marketAddress) public view returns (Prediction[] memory) {
return marketPredictions[marketAddress];
}

function addPrediction(address marketAddress, Prediction memory prediction) public {
require(address(msg.sender) == address(prediction.publisherAddress), "Only publisher can add a prediction");
marketPredictions[marketAddress].push(prediction);
emit PredictionAdded(
marketAddress, prediction.estimatedProbabilityBps, msg.sender, prediction.txHash, prediction.ipfsHash
);
}

function getPredictionByIndex(address marketAddress, uint256 index) public view returns (Prediction memory) {
require(index < marketPredictions[marketAddress].length, "Index out of bounds");
return marketPredictions[marketAddress][index];
}
}
9 changes: 9 additions & 0 deletions src/structs.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

struct Prediction {
address publisherAddress;
bytes32 ipfsHash;
bytes32 txHash;
uint16 estimatedProbabilityBps; // in basis points, 0-10000
}
88 changes: 88 additions & 0 deletions test/OmenAgentResultMapping.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.13;

import {Test} from "forge-std/Test.sol";
import {OmenAgentResultMapping} from "../src/OmenAgentResultMapping.sol";
import {Prediction} from "../src/structs.sol";

contract OmenAgentResultMappingTest is Test {
OmenAgentResultMapping public omenAgentResultMapping;
address publisher;
address marketAddress;

function setUp() public {
omenAgentResultMapping = new OmenAgentResultMapping();
publisher = vm.addr(1);
// We mock the market address value as being the address of this test contract.
marketAddress = address(this);
}

function buildPrediction(string memory input) internal view returns (Prediction memory) {
// Convert the input string to a bytes32 IPFS hash
bytes32 ipfsHash = keccak256(abi.encodePacked(input));
bytes32 dummyTxHash = keccak256(abi.encodePacked("dummy transaction hash"));
uint16 estimatedProbabilityBps = 6556; //65.56%
Prediction memory prediction = Prediction(publisher, ipfsHash, dummyTxHash, estimatedProbabilityBps);
return prediction;
}

function addMockPrediction(string memory input) internal returns (bytes32) {
Prediction memory prediction = buildPrediction(input);
vm.prank(publisher);
omenAgentResultMapping.addPrediction(marketAddress, prediction);
return prediction.ipfsHash;
}

function testAddAndGetPredictions() public {
// Add a mock prediction and capture the IPFS hash
bytes32 expectedHash1 = addMockPrediction("test-input1");
bytes32 expectedHash2 = addMockPrediction("test-input2");

Prediction[] memory predictions = omenAgentResultMapping.getPredictions(address(this));
assertEq(predictions[0].ipfsHash, expectedHash1);
assertEq(predictions[1].ipfsHash, expectedHash2);
}

function testAddPredictionRevertsForNonPublisher() public {
Prediction memory prediction = buildPrediction("test-input1");

vm.startPrank(vm.addr(2));
vm.expectRevert();
omenAgentResultMapping.addPrediction(marketAddress, prediction);
vm.stopPrank();
}

function testAddPredictionEmitsEvent() public {
Prediction memory prediction = buildPrediction("test-input1");

vm.expectEmit(true, true, false, true);
vm.startPrank(publisher);
emit OmenAgentResultMapping.PredictionAdded(
marketAddress,
prediction.estimatedProbabilityBps,
prediction.publisherAddress,
prediction.txHash,
prediction.ipfsHash
);
omenAgentResultMapping.addPrediction(marketAddress, prediction);
vm.stopPrank();
}

function testGetByIndex() public {
bytes32 hash1 = addMockPrediction("test-string-1");
bytes32 hash2 = addMockPrediction("test-string-2");
bytes32 hash3 = addMockPrediction("test-string-3");

Prediction memory prediction1 = omenAgentResultMapping.getPredictionByIndex(marketAddress, 0);
Prediction memory prediction2 = omenAgentResultMapping.getPredictionByIndex(marketAddress, 1);
Prediction memory prediction3 = omenAgentResultMapping.getPredictionByIndex(marketAddress, 2);

assertEq(prediction1.ipfsHash, hash1);
assertEq(prediction2.ipfsHash, hash2);
assertEq(prediction3.ipfsHash, hash3);

// Expect a revert when trying to access an out-of-bounds index
vm.expectRevert();
omenAgentResultMapping.getPredictionByIndex(publisher, 3); // Out of bounds
}
}

0 comments on commit cfe4296

Please sign in to comment.