diff --git a/.gitignore b/.gitignore index 287fb9b..79723b8 100644 --- a/.gitignore +++ b/.gitignore @@ -102,4 +102,6 @@ lint/tmp/ gas-report.txt contracts/test/fuzzing/crytic-export -temp \ No newline at end of file +temp + +yarn.lock \ No newline at end of file diff --git a/contracts/DealStatus.sol b/contracts/DealStatus.sol index db369e6..4c8b722 100644 --- a/contracts/DealStatus.sol +++ b/contracts/DealStatus.sol @@ -5,18 +5,39 @@ pragma solidity ^0.8.17; // import "hardhat/console.sol"; import "./interfaces/IAggregatorOracle.sol"; -import "./data-segment/Proof.sol"; +import {Proof} from "./data-segment/Proof.sol"; +import {MarketTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/MarketTypes.sol"; +import {MarketAPI} from "@zondax/filecoin-solidity/contracts/v0.8/MarketAPI.sol"; +import {CommonTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/CommonTypes.sol"; // Delta that implements the AggregatorOracle interface contract DealStatus is IAggregatorOracle, Proof { + /////////////////// + // State Variables + /////////////////// + uint256 private transactionId; mapping(uint256 => bytes) private txIdToCid; mapping(bytes => Deal[]) private cidToDeals; + /////////////////// + // Functions + /////////////////// + + //constructor constructor() { transactionId = 0; } + // external functions + + /** + * @notice Submits a new transaction with the given content identifier. + * @dev Increments the transaction ID, saves the content identifier, and emits a SubmitAggregatorRequest event. + * @param _cid The content identifier for the new transaction. + * @return The ID of the newly created transaction. + */ + function submit(bytes memory _cid) external returns (uint256) { // Increment the transaction ID transactionId++; @@ -29,11 +50,21 @@ contract DealStatus is IAggregatorOracle, Proof { return transactionId; } + /** + * @notice Submits a new transaction with the given content identifier and RaaS parameters. + * @dev Increments the transaction ID, saves the content identifier, and emits a SubmitAggregatorRequestWithRaaS event. + * @param _cid The content identifier for the new transaction. + * @param _replication_target The number of replications of data needed. + * @param _repair_threshold The threshold to repair the deal if miner faults. + * @param _renew_threshold The threshold to renew the deal. + * @return The ID of the newly created transaction. + */ + function submitRaaS( bytes memory _cid, - uint256 _replication_target, + uint256 _replication_target, uint256 _repair_threshold, - uint256 _renew_threshold + uint256 _renew_threshold ) external returns (uint256) { // Increment the transaction ID transactionId++; @@ -42,10 +73,27 @@ contract DealStatus is IAggregatorOracle, Proof { txIdToCid[transactionId] = _cid; // Emit the event - emit SubmitAggregatorRequestWithRaaS(transactionId, _cid, _replication_target, _repair_threshold, _renew_threshold); + emit SubmitAggregatorRequestWithRaaS( + transactionId, + _cid, + _replication_target, + _repair_threshold, + _renew_threshold + ); return transactionId; } + /** + * @notice Completes a transaction with the given transaction ID, deal ID, miner ID, inclusion proof, and inclusion verifier data. + * @dev Emits a CompleteAggregatorRequest event. + * @param _id The ID of the transaction to complete. + * @param _dealId The ID of the deal to complete. + * @param _minerId The ID of the miner that completed the deal. + * @param _proof The inclusion proof for the transaction. + * @param _verifierData The inclusion verifier data for the transaction. + * @return The inclusion auxiliary data proof for the given file proof and verifier data. + */ + function complete( uint256 _id, uint64 _dealId, @@ -61,7 +109,7 @@ contract DealStatus is IAggregatorOracle, Proof { bytes memory cid = txIdToCid[_id]; for (uint256 i = 0; i < cidToDeals[cid].length; i++) { if (cidToDeals[cid][i].dealId == _dealId) { - return this.computeExpectedAuxData(_proof, _verifierData); + return computeExpectedAuxData(_proof, _verifierData); } } @@ -70,24 +118,19 @@ contract DealStatus is IAggregatorOracle, Proof { // Perform validation logic // return this.computeExpectedAuxDataWithDeal(_dealId, _proof, _verifierData); - return this.computeExpectedAuxData(_proof, _verifierData); + return computeExpectedAuxData(_proof, _verifierData); } - // allDealIds should return all the deal ids created by the aggregator - function getAllDeals(bytes memory _cid) external view returns (Deal[] memory) { - return cidToDeals[_cid]; - } + // View functions - function getAllCIDs() external view returns (bytes[] memory) { - bytes[] memory cids = new bytes[](transactionId); - for (uint256 i = 0; i < transactionId; i++) { - cids[i] = txIdToCid[i + 1]; - } - return cids; - } + /** + * @notice Retrieves all active deals associated with a given content identifier. + * @dev Iterates through all deals associated with the content identifier, checks their activation and termination status, and removes any inactive deals from the returned array. + * @param _cid The content identifier for which to retrieve active deals. + * @return An array of Deal structs representing all active deals associated with the given content identifier. + */ - // getActiveDeals should return all the _cid's active dealIds - function getActiveDeals(bytes memory _cid) external returns (Deal[] memory) { + function getActiveDeals(bytes memory _cid) external view returns (Deal[] memory) { // get all the deal ids for the cid Deal[] memory activeDealIds; activeDealIds = this.getAllDeals(_cid); @@ -95,9 +138,9 @@ contract DealStatus is IAggregatorOracle, Proof { for (uint256 i = 0; i < activeDealIds.length; i++) { uint64 dealID = activeDealIds[i].dealId; // get the deal's expiration epoch - MarketTypes.GetDealActivationReturn memory dealActivationStatus = MarketAPI.getDealActivation(dealID); + (int64 activated, int64 terminated) = this.getDealActivationData(dealID); - if (dealActivationStatus.terminated > 0 || dealActivationStatus.activated == -1) { + if (terminated > 0 || activated == -1) { delete activeDealIds[i]; } } @@ -105,8 +148,18 @@ contract DealStatus is IAggregatorOracle, Proof { return activeDealIds; } - // getExpiringDeals should return all the deals' dealIds if they are expiring within `epochs` - function getExpiringDeals(bytes memory _cid, uint64 epochs) external returns (Deal[] memory) { + /** + * @notice Retrieves all expiring deals associated with a given content identifier. + * @dev Iterates through all deals associated with the content identifier, checks their expiration status, and removes any non-expiring deals from the returned array. + * @param _cid The content identifier for which to retrieve expiring deals. + * @param epochs The number of epochs before a deal's expiration to consider it expiring. + * @return An array of Deal structs representing all expiring deals associated with the given content identifier. + */ + + function getExpiringDeals( + bytes memory _cid, + uint64 epochs + ) external view returns (Deal[] memory) { // the logic is similar to the above, but use this api call: // https://github.com/Zondax/filecoin-solidity/blob/master/contracts/v0.8/MarketAPI.sol#LL110C9-L110C9 Deal[] memory expiringDealIds; @@ -115,13 +168,78 @@ contract DealStatus is IAggregatorOracle, Proof { for (uint256 i = 0; i < expiringDealIds.length; i++) { uint64 dealId = expiringDealIds[i].dealId; // get the deal's expiration epoch - MarketTypes.GetDealTermReturn memory dealTerm = MarketAPI.getDealTerm(dealId); - - if (block.number < uint64(dealTerm.end) - epochs || block.number > uint64(dealTerm.end)) { + (int64 startEpoch, int64 duration) = this.getDealTermData(dealId); + if ( + (block.number + epochs < uint64(startEpoch) + uint64(duration)) || + (block.number > uint64(startEpoch) + uint64(duration)) + ) { delete expiringDealIds[i]; } } return expiringDealIds; } + + //Getter Functions + + /** + * @notice Retrieves the activation and termination data for a given deal. + * @dev Calls the MarketAPI to get the deal's activation status and then unwraps the activation and termination epochs. + * @param _dealId The ID of the deal for which to retrieve activation data. + * @return dealActivation The activation epoch of the deal or -1. + * @return dealTermination The termination epoch of the deal or -1. + */ + + function getDealActivationData( + uint64 _dealId + ) public view returns (int64 dealActivation, int64 dealTermination) { + MarketTypes.GetDealActivationReturn memory dealActivationStatus = MarketAPI + .getDealActivation(_dealId); + return ( + CommonTypes.ChainEpoch.unwrap(dealActivationStatus.activated), + CommonTypes.ChainEpoch.unwrap(dealActivationStatus.terminated) + ); + } + + /** + * @notice Retrieves the start and end epochs for a given deal. + * @dev Calls the MarketAPI to get the deal's start and end epochs and then unwraps them. + * @param _dealId The ID of the deal for which to retrieve term data. + * @return startEpoch The start epoch of the deal. + * @return endEpoch The end epoch of the deal. + */ + function getDealTermData( + uint64 _dealId + ) public view returns (int64 startEpoch, int64 endEpoch) { + MarketTypes.GetDealTermReturn memory dealTerm = MarketAPI.getDealTerm(_dealId); + return ( + CommonTypes.ChainEpoch.unwrap(dealTerm.start), + CommonTypes.ChainEpoch.unwrap(dealTerm.end) + ); + } + + /** + * @notice Retrieves all deals associated with a given content identifier. + * @dev Returns the array of deals associated with the given content identifier. + * @param _cid The content identifier for which to retrieve deals. + * @return An array of Deal structs representing all deals associated with the given content identifier. + */ + + function getAllDeals(bytes memory _cid) external view returns (Deal[] memory) { + return cidToDeals[_cid]; + } + + /** + * @notice Retrieves all content identifiers associated with the contract. + * @dev Returns the array of content identifiers associated with the aggregator. + * @return An array of bytes representing all content identifiers associated with the aggregator. + */ + + function getAllCIDs() external view returns (bytes[] memory) { + bytes[] memory cids = new bytes[](transactionId); + for (uint256 i = 0; i < transactionId; i++) { + cids[i] = txIdToCid[i + 1]; + } + return cids; + } } diff --git a/contracts/data-segment/Cid.sol b/contracts/data-segment/Cid.sol index 7b563f2..d70b527 100644 --- a/contracts/data-segment/Cid.sol +++ b/contracts/data-segment/Cid.sol @@ -7,11 +7,14 @@ import "./Const.sol"; library Cid { // cidToPieceCommitment converts a CID to a piece commitment. - function cidToPieceCommitment(bytes memory _cb) public pure returns (bytes32) { - require(_cb.length == CID_COMMP_HEADER_LENGTH + MERKLE_TREE_NODE_SIZE, "wrong length of CID"); + function cidToPieceCommitment(bytes memory _cb) internal pure returns (bytes32) { require( - keccak256(abi.encodePacked(_cb[0], _cb[1], _cb[2], _cb[3], _cb[4], _cb[5], _cb[6])) - == keccak256(abi.encodePacked(CID_COMMP_HEADER)), + _cb.length == CID_COMMP_HEADER_LENGTH + MERKLE_TREE_NODE_SIZE, + "wrong length of CID" + ); + require( + keccak256(abi.encodePacked(_cb[0], _cb[1], _cb[2], _cb[3], _cb[4], _cb[5], _cb[6])) == + keccak256(abi.encodePacked(CID_COMMP_HEADER)), "wrong content of CID header" ); bytes32 res; @@ -22,7 +25,7 @@ library Cid { } // pieceCommitmentToCid converts a piece commitment to a CID. - function pieceCommitmentToCid(bytes32 _commp) public pure returns (bytes memory) { + function pieceCommitmentToCid(bytes32 _commp) internal pure returns (bytes memory) { bytes memory cb = abi.encodePacked(CID_COMMP_HEADER, _commp); return cb; } diff --git a/contracts/data-segment/Proof.sol b/contracts/data-segment/Proof.sol index 1c11c67..26f3cec 100644 --- a/contracts/data-segment/Proof.sol +++ b/contracts/data-segment/Proof.sol @@ -9,34 +9,44 @@ import {Cid} from "./Cid.sol"; import {ProofData, InclusionProof, InclusionVerifierData, InclusionAuxData, SegmentDesc, Fr32} from "./ProofTypes.sol"; import {MarketAPI} from "@zondax/filecoin-solidity/contracts/v0.8/MarketAPI.sol"; import {MarketTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/MarketTypes.sol"; - +import {CommonTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/CommonTypes.sol"; contract Proof { using Cid for bytes; using Cid for bytes32; // computeExpectedAuxData computes the expected auxiliary data given an inclusion proof and the data provided by the verifier. - function computeExpectedAuxData(InclusionProof memory ip, InclusionVerifierData memory verifierData) - public - pure - returns (InclusionAuxData memory) - { - require(isPow2(uint64(verifierData.sizePc)), "Size of piece provided by verifier is not power of two"); + function computeExpectedAuxData( + InclusionProof memory ip, + InclusionVerifierData memory verifierData + ) internal pure returns (InclusionAuxData memory) { + require( + isPow2(uint64(verifierData.sizePc)), + "Size of piece provided by verifier is not power of two" + ); bytes32 commPc = verifierData.commPc.cidToPieceCommitment(); bytes32 assumedCommPa = computeRoot(ip.proofSubtree, commPc); - (bool ok, uint64 assumedSizePa) = - checkedMultiply(uint64(1) << uint64(ip.proofSubtree.path.length), uint64(verifierData.sizePc)); + (bool ok, uint64 assumedSizePa) = checkedMultiply( + uint64(1) << uint64(ip.proofSubtree.path.length), + uint64(verifierData.sizePc) + ); require(ok, "assumedSizePa overflow"); uint64 dataOffset = ip.proofSubtree.index * uint64(verifierData.sizePc); - SegmentDesc memory en = makeDataSegmentIndexEntry(Fr32(commPc), dataOffset, uint64(verifierData.sizePc)); + SegmentDesc memory en = makeDataSegmentIndexEntry( + Fr32(commPc), + dataOffset, + uint64(verifierData.sizePc) + ); bytes32 enNode = truncatedHash(serialize(en)); bytes32 assumedCommPa2 = computeRoot(ip.proofIndex, enNode); require(assumedCommPa == assumedCommPa2, "aggregator's data commitments don't match"); - (bool ok2, uint64 assumedSizePa2) = - checkedMultiply(uint64(1) << uint64(ip.proofIndex.path.length), BYTES_IN_DATA_SEGMENT_ENTRY); + (bool ok2, uint64 assumedSizePa2) = checkedMultiply( + uint64(1) << uint64(ip.proofIndex.path.length), + BYTES_IN_DATA_SEGMENT_ENTRY + ); require(ok2, "assumedSizePau64 overflow"); require(assumedSizePa == assumedSizePa2, "aggregator's data size doesn't match"); @@ -50,34 +60,46 @@ contract Proof { uint64 dealId, InclusionProof memory ip, InclusionVerifierData memory verifierData - ) public returns (InclusionAuxData memory) { + ) internal view returns (InclusionAuxData memory) { InclusionAuxData memory inclusionAuxData = computeExpectedAuxData(ip, verifierData); validateInclusionAuxData(dealId, inclusionAuxData); return inclusionAuxData; } // validateInclusionAuxData validates that the deal is activated and not terminated. - function validateInclusionAuxData(uint64 dealId, InclusionAuxData memory inclusionAuxData) internal { + function validateInclusionAuxData( + uint64 dealId, + InclusionAuxData memory inclusionAuxData + ) internal view { // check that the deal is not terminated - MarketTypes.GetDealActivationReturn memory dealActivation = MarketAPI.getDealActivation(dealId); - require(dealActivation.terminated <= 0, "Deal is terminated"); - require(dealActivation.activated > 0, "Deal is not activated"); - - MarketTypes.GetDealDataCommitmentReturn memory dealDataCommitment = MarketAPI.getDealDataCommitment(dealId); - require(keccak256(dealDataCommitment.data) == keccak256(inclusionAuxData.commPa), "Deal commD doesn't match"); + MarketTypes.GetDealActivationReturn memory dealActivation = MarketAPI.getDealActivation( + dealId + ); + require(CommonTypes.ChainEpoch.unwrap(dealActivation.terminated) <= 0, "Deal is terminated"); + require(CommonTypes.ChainEpoch.unwrap(dealActivation.activated )> 0, "Deal is not activated"); + + MarketTypes.GetDealDataCommitmentReturn memory dealDataCommitment = MarketAPI + .getDealDataCommitment(dealId); + require( + keccak256(dealDataCommitment.data) == keccak256(inclusionAuxData.commPa), + "Deal commD doesn't match" + ); require(dealDataCommitment.size == inclusionAuxData.sizePa, "Deal size doesn't match"); } // validateIndexEntry validates that the index entry is in the correct position in the index. function validateIndexEntry(InclusionProof memory ip, uint64 assumedSizePa2) internal pure { uint64 idxStart = indexAreaStart(assumedSizePa2); - (bool ok3, uint64 indexOffset) = checkedMultiply(ip.proofIndex.index, BYTES_IN_DATA_SEGMENT_ENTRY); + (bool ok3, uint64 indexOffset) = checkedMultiply( + ip.proofIndex.index, + BYTES_IN_DATA_SEGMENT_ENTRY + ); require(ok3, "indexOffset overflow"); require(indexOffset >= idxStart, "index entry at wrong position"); } // computeRoot computes the root of a Merkle tree given a leaf and a Merkle proof. - function computeRoot(ProofData memory d, bytes32 subtree) public pure returns (bytes32) { + function computeRoot(ProofData memory d, bytes32 subtree) internal pure returns (bytes32) { require(d.path.length < 64, "merkleproofs with depths greater than 63 are not supported"); require(d.index >> d.path.length == 0, "index greater than width of the tree"); @@ -98,7 +120,7 @@ contract Proof { } // computeNode computes the parent node of two child nodes - function computeNode(bytes32 left, bytes32 right) public pure returns (bytes32) { + function computeNode(bytes32 left, bytes32 right) internal pure returns (bytes32) { bytes32 digest = sha256(abi.encodePacked(left, right)); return truncate(digest); } @@ -145,7 +167,11 @@ contract Proof { } // verify verifies that the given leaf is present in the merkle tree with the given root. - function verify(ProofData memory proof, bytes32 root, bytes32 leaf) public pure returns (bool) { + function verify( + ProofData memory proof, + bytes32 root, + bytes32 leaf + ) internal pure returns (bool) { return computeRoot(proof, leaf) == root; } @@ -159,25 +185,25 @@ contract Proof { } // hashNode hashes the given node with the given left child. - function hashNode(bytes32 left, bytes32 right) public pure returns (bytes32) { + function hashNode(bytes32 left, bytes32 right) internal pure returns (bytes32) { bytes32 truncatedData = sha256(abi.encodePacked(left, right)); truncatedData &= TRUNCATOR; return truncatedData; } // truncatedHash computes the truncated hash of the given data. - function truncatedHash(bytes memory data) public pure returns (bytes32) { + function truncatedHash(bytes memory data) internal pure returns (bytes32) { bytes32 truncatedData = sha256(abi.encodePacked(data)); truncatedData &= TRUNCATOR; return truncatedData; } // makeDataSegmentIndexEntry creates a new data segment index entry. - function makeDataSegmentIndexEntry(Fr32 memory commP, uint64 offset, uint64 size) - internal - pure - returns (SegmentDesc memory) - { + function makeDataSegmentIndexEntry( + Fr32 memory commP, + uint64 offset, + uint64 size + ) internal pure returns (SegmentDesc memory) { SegmentDesc memory en; en.commDs = bytes32(commP.value); en.offset = offset; @@ -187,7 +213,7 @@ contract Proof { } // computeChecksum computes the checksum of the given segment description. - function computeChecksum(SegmentDesc memory _sd) public pure returns (bytes16) { + function computeChecksum(SegmentDesc memory _sd) internal pure returns (bytes16) { bytes memory serialized = serialize(_sd); bytes32 digest = sha256(serialized); digest &= hex"ffffffffffffffffffffffffffffff3f"; @@ -195,7 +221,7 @@ contract Proof { } // serialize serializes the given segment description. - function serialize(SegmentDesc memory sd) public pure returns (bytes memory) { + function serialize(SegmentDesc memory sd) internal pure returns (bytes memory) { bytes memory result = new bytes(ENTRY_SIZE); // Pad commDs diff --git a/contracts/mocks/DealStatusMock.sol b/contracts/mocks/DealStatusMock.sol index 854de95..192172e 100644 --- a/contracts/mocks/DealStatusMock.sol +++ b/contracts/mocks/DealStatusMock.sol @@ -34,9 +34,9 @@ contract DealStatusMock is IAggregatorOracle, ProofMock { function submitRaaS( bytes memory _cid, - uint256 _replication_target, + uint256 _replication_target, uint256 _repair_threshold, - uint256 _renew_threshold + uint256 _renew_threshold ) external returns (uint256) { // Increment the transaction ID transactionId++; @@ -45,7 +45,13 @@ contract DealStatusMock is IAggregatorOracle, ProofMock { txIdToCid[transactionId] = _cid; // Emit the event - emit SubmitAggregatorRequestWithRaaS(transactionId, _cid, _replication_target, _repair_threshold, _renew_threshold); + emit SubmitAggregatorRequestWithRaaS( + transactionId, + _cid, + _replication_target, + _repair_threshold, + _renew_threshold + ); return transactionId; } @@ -83,7 +89,7 @@ contract DealStatusMock is IAggregatorOracle, ProofMock { } // getActiveDeals should return all the _cid's active dealIds - function getActiveDeals(bytes memory _cid) external returns (Deal[] memory) { + function getActiveDeals(bytes memory _cid) external view returns (Deal[] memory) { // get all the deal ids for the cid Deal[] memory activeDealIds; activeDealIds = this.getAllDeals(_cid); @@ -91,9 +97,13 @@ contract DealStatusMock is IAggregatorOracle, ProofMock { for (uint256 i = 0; i < activeDealIds.length; i++) { uint64 dealID = activeDealIds[i].dealId; // get the deal's expiration epoch - MarketTypes.GetDealActivationReturn memory dealActivationStatus = MarketAPI.getDealActivation(dealID); + MarketTypes.GetDealActivationReturn memory dealActivationStatus = MarketAPI + .getDealActivation(dealID); - if (dealActivationStatus.terminated > 0 || dealActivationStatus.activated == -1) { + if ( + CommonTypes.ChainEpoch.unwrap(dealActivationStatus.terminated) > 0 || + CommonTypes.ChainEpoch.unwrap(dealActivationStatus.activated) == -1 + ) { delete activeDealIds[i]; } } @@ -102,7 +112,10 @@ contract DealStatusMock is IAggregatorOracle, ProofMock { } // getExpiringDeals should return all the deals' dealIds if they are expiring within `epochs` - function getExpiringDeals(bytes memory _cid,uint64 epochs) external view returns (Deal[] memory) { + function getExpiringDeals( + bytes memory _cid, + uint64 epochs + ) external view returns (Deal[] memory) { // the logic is similar to the above, but use this api call: // https://github.com/Zondax/filecoin-solidity/blob/master/contracts/v0.8/MarketAPI.sol#LL110C9-L110C9 Deal[] memory expiringDealIds; @@ -113,7 +126,14 @@ contract DealStatusMock is IAggregatorOracle, ProofMock { // get the deal's expiration epoch MarketTypes.GetDealTermReturn memory dealTerm = MarketAPI.getDealTerm(dealId); - if (block.number < uint64(dealTerm.end) - epochs || block.number > uint64(dealTerm.end)) { + if ( + (block.number + epochs < + uint64(CommonTypes.ChainEpoch.unwrap(dealTerm.start)) + + uint64(CommonTypes.ChainEpoch.unwrap(dealTerm.end))) || + (block.number > + uint64(CommonTypes.ChainEpoch.unwrap(dealTerm.start)) + + uint64(CommonTypes.ChainEpoch.unwrap(dealTerm.end))) + ) { delete expiringDealIds[i]; } } diff --git a/contracts/mocks/MarketAPIMock.sol b/contracts/mocks/MarketAPIMock.sol index 92049c2..67cb5ff 100644 --- a/contracts/mocks/MarketAPIMock.sol +++ b/contracts/mocks/MarketAPIMock.sol @@ -70,7 +70,7 @@ library MarketAPI { /// @notice Get the start epoch and duration(in epochs) of a deal proposal. /// @return the start epoch and duration (in epochs) of a deal proposal. function getDealTerm(uint64 dealID) internal pure returns (MarketTypes.GetDealTermReturn memory) { - return MarketTypes.GetDealTermReturn({start: 0, end: 1000}); + return MarketTypes.GetDealTermReturn({start: CommonTypes.ChainEpoch.wrap(0), end: CommonTypes.ChainEpoch.wrap(1000)}); } /// @notice get the total price that will be paid from the client to the provider for this deal. @@ -94,7 +94,7 @@ library MarketAPI { /// @notice This will be available from when the proposal is published until an undefined period after the deal finishes (either normally or by termination). /// @return USR_NOT_FOUND if the deal doesn't exist (yet), or EX_DEAL_EXPIRED if the deal has been removed from state. function getDealActivation(uint64 dealID) internal pure returns (MarketTypes.GetDealActivationReturn memory) { - return MarketTypes.GetDealActivationReturn({activated: 0, terminated: -1}); + return MarketTypes.GetDealActivationReturn({activated: CommonTypes.ChainEpoch.wrap(0), terminated: CommonTypes.ChainEpoch.wrap(-1)}); } /// @notice Publish a new set of storage deals (not yet included in a sector). diff --git a/contracts/mocks/ProofMock.sol b/contracts/mocks/ProofMock.sol index 5779e93..2d21d26 100644 --- a/contracts/mocks/ProofMock.sol +++ b/contracts/mocks/ProofMock.sol @@ -16,7 +16,7 @@ import { } from "../data-segment/ProofTypes.sol"; import {MarketAPI} from "./MarketAPIMock.sol"; import {MarketTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/MarketTypes.sol"; - +import {CommonTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/CommonTypes.sol"; contract ProofMock { using Cid for bytes; using Cid for bytes32; @@ -67,8 +67,8 @@ contract ProofMock { function validateInclusionAuxData(uint64 dealId, InclusionAuxData memory inclusionAuxData) internal { // check that the deal is not terminated MarketTypes.GetDealActivationReturn memory dealActivation = MarketAPI.getDealActivation(dealId); - require(dealActivation.terminated <= 0, "Deal is terminated"); - require(dealActivation.activated > 0, "Deal is not activated"); + require(CommonTypes.ChainEpoch.unwrap(dealActivation.terminated) <= 0, "Deal is terminated"); + require(CommonTypes.ChainEpoch.unwrap(dealActivation.activated) > 0, "Deal is not activated"); MarketTypes.GetDealDataCommitmentReturn memory dealDataCommitment = MarketAPI.getDealDataCommitment(dealId); require(keccak256(dealDataCommitment.data) == keccak256(inclusionAuxData.commPa), "Deal commD doesn't match"); diff --git a/deploy/00_deploy.js b/deploy/00_deploy.js index 7f743db..9761630 100644 --- a/deploy/00_deploy.js +++ b/deploy/00_deploy.js @@ -8,46 +8,44 @@ const wallet = new ethers.Wallet(private_key, ethers.provider) module.exports = async ({ deployments }) => { // ethers is available in the global scope - const [deployer] = await ethers.getSigners(); + const [deployer] = await ethers.getSigners() console.log( "Deploying the contracts with the account:", - await deployer.getAddress() - ); - - console.log("Account balance:", (await deployer.getBalance()).toString()); - - const accounts = await ethers.getSigners(); - //console.log(accounts[0]) - - console.log("Wallet Ethereum Address:", wallet.address); - const chainId = network.config.chainId; - - //deploy DealStatus - const Cid = await ethers.getContractFactory('Cid', accounts[0]); - console.log('Deploying Cid...'); - const cid = await Cid.deploy(); - await cid.deployed() - console.log('Cid deployed to:', cid.address); - - //deploy DealStatus - const Proof = await ethers.getContractFactory('Proof', { - libraries: { - Cid: cid.address, - }, - }); - console.log('Deploying Proof...'); - const proof = await Proof.deploy(); - await proof.deployed() - console.log('Proof deployed to:', proof.address); + await deployer.getAddress(), + "on network", + network.name + ) + + console.log("Account balance:", (await deployer.getBalance()).toString()) + + const accounts = await ethers.getSigners() + // console.log(accounts[0]) + + console.log("Wallet Ethereum Address:", wallet.address) + // const chainId = network.config.chainId + + // //deploy DealStatus + // const Cid = await ethers.getContractFactory('Cid', accounts[0]); + // console.log('Deploying Cid...'); + // const cid = await Cid.deploy(); + // await cid.deployed() + // console.log('Cid deployed to:', cid.address); + + // //deploy DealStatus + // const Proof = await ethers.getContractFactory('Proof', { + // libraries: { + // Cid: cid.address, + // }, + // }); + // console.log('Deploying Proof...'); + // const proof = await Proof.deploy(); + // await proof.deployed() + // console.log('Proof deployed to:', proof.address); //deploy DealStatus - const dealStatus = await ethers.getContractFactory('DealStatus', { - libraries: { - Cid: cid.address, - }, - }); - console.log('Deploying DealStatus...'); - const dealstatus = await dealStatus.deploy(); + const dealStatus = await ethers.getContractFactory("DealStatus", accounts[0]) + console.log("Deploying DealStatus...") + const dealstatus = await dealStatus.deploy() await dealstatus.deployed() - console.log('DealStatus deployed to:', dealstatus.address); + console.log("DealStatus deployed to:", dealstatus.address) } diff --git a/hardhat.config.js b/hardhat.config.js index 90c0f47..1f91f9f 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -10,13 +10,13 @@ module.exports = { solidity: { version: "0.8.17", settings: { - optimizer: { - enabled: true, - runs: 1000, - details: { yul: false }, - }, + optimizer: { + enabled: true, + runs: 1000, + details: { yul: false }, + }, }, - }, + }, defaultNetwork: "calibrationnet", mocha: { timeout: 100000000 diff --git a/package.json b/package.json index 9d5d4d7..6a8bb73 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,8 @@ "@nomicfoundation/hardhat-network-helpers": "^1.0.0", "@nomicfoundation/hardhat-toolbox": "^2.0.0", "@nomiclabs/hardhat-ethers": "^2.2.3", - "@openzeppelin/contracts": "^4.8.3", + "@openzeppelin/contracts": "^5.0.0", + "@openzeppelin/contracts-upgradeable": "^5.0.0", "@typechain/hardhat": "^6.1.2", "@zondax/filecoin-solidity": "^2.0.0-beta.1", "babel-eslint": "^10.1.0", @@ -58,6 +59,7 @@ "html-webpack-plugin": "^5.5.3", "multer": "^1.4.5-lts.1", "sinon": "^15.2.0", + "solidity-cborutils": "^2.0.0", "ts-node": "^10.9.1", "typescript": "^4.9.4", "webpack-cli": "^5.1.4", diff --git a/tasks/deal-client/get-deal-status b/tasks/deal-client/get-deal-status.js similarity index 100% rename from tasks/deal-client/get-deal-status rename to tasks/deal-client/get-deal-status.js diff --git a/tasks/deal-status/get-deal-info.js b/tasks/deal-status/get-deal-info.js new file mode 100644 index 0000000..acc7546 --- /dev/null +++ b/tasks/deal-status/get-deal-info.js @@ -0,0 +1,39 @@ +task("get-deal-info", "Gets a deal's info from deal id") + .addParam("contract", "The address of the DealRewarder contract") + .addParam("dealId", "The deal id of the deal you want the info of") + .setAction(async (taskArgs) => { + const contractAddr = taskArgs.contract + const networkId = network.name + const dealId = taskArgs.dealId + console.log("Running dealStatus on network", networkId) + + //create a new wallet instance + const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider) + + const DealStatus = await ethers.getContractFactory("DealStatus", wallet) + + const dealStatus = await DealStatus.attach(contractAddr) + + const dealActivationReturn = await dealStatus.getDealActivationData(dealId) + console.log("Deal Activation return data is: ", dealActivationReturn) + console.log("Which gets parsed to:") + printBigIntChainOutput(dealActivationReturn) + const dealTermReturn = await dealStatus.getDealTermData(dealId) + console.log("Deal Term return data is: ", dealTermReturn) + console.log("Which gets parsed to:") + printBigIntChainOutput(dealTermReturn) + + console.log("Complete!") + + // Converts the BigInt return data from a view function to a readable format + function printBigIntChainOutput(output) { + for (let i = 0; i < output.length; i++) { + console.log( + Object.keys(output)[i + output.length], + ":", + Number(Object.values(output)[i]._hex) + ) + } + } + }) +//sample contract 0xc3B1D57038BD4a2263e56c3bE8689d4B3Cc7C786 diff --git a/tasks/index.js b/tasks/index.js index b28bbe7..f0e41dd 100644 --- a/tasks/index.js +++ b/tasks/index.js @@ -9,4 +9,5 @@ exports.fund = require("./deal-rewarder/fund") exports.claimBounty = require("./deal-rewarder/claim-bounty") exports.makeDealProposal = require("./deal-client/make-deal-proposal") exports.getDealProposal = require("./deal-client/get-deal-proposal") -exports.getDealStatus = require("./deal-client/get-deal-status") \ No newline at end of file +exports.getDealStatus = require("./deal-client/get-deal-status") +exports.getDealInfo = require("./deal-status/get-deal-info")