Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
Bring mock contracts to the repo (#58)
Browse files Browse the repository at this point in the history
* add mock api files
* add commands to makefile
* add build workflow
* fix hardhat deploy
* apply some improvements and fixes on docs
* fix build mismatch error
  • Loading branch information
emmanuelm41 authored Dec 9, 2022
1 parent 18566f8 commit 844836d
Show file tree
Hide file tree
Showing 16 changed files with 1,168 additions and 105 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@ on:
- push

jobs:
build-mock:
name: "Build Mock API"
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install node
uses: actions/setup-node@v2
with:
node-version: '16.16.0'
- name: Install yarn
run: npm install -g yarn
- name: Install dependencies
run: |
yarn install
make install_solc_linux
- name: Compile contract files
run: make build_mock_api

simplecoin-checks:
name: "SimpleCoin: end-to-end tests"
timeout-minutes: 20
Expand Down
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
build: build_api
build: build_api build_mock_api

deploy_api: deploy_miner_api deploy_market_api deploy_verifreg_api deploy_power_api

Expand All @@ -24,6 +24,11 @@ build_api:
./bin/solc solidity-cborutils=${PWD}/node_modules/solidity-cborutils/ @openzeppelin=${PWD}/node_modules/@openzeppelin/ @ensdomains=${PWD}/node_modules/@ensdomains/ contracts/v0.8/AccountAPI.sol --output-dir ./build/v0.8 --overwrite --bin --hashes --opcodes --abi
./bin/solc solidity-cborutils=${PWD}/node_modules/solidity-cborutils/ @openzeppelin=${PWD}/node_modules/@openzeppelin/ @ensdomains=${PWD}/node_modules/@ensdomains/ contracts/v0.8/MultisigAPI.sol --output-dir ./build/v0.8 --overwrite --bin --hashes --opcodes --abi

build_mock_api:
./bin/solc solidity-cborutils=${PWD}/node_modules/solidity-cborutils/ @openzeppelin=${PWD}/node_modules/@openzeppelin/ @ensdomains=${PWD}/node_modules/@ensdomains/ contracts/v0.8/mocks/MarketAPI.sol --output-dir ./build/v0.8/mocks --overwrite --bin --hashes --opcodes --abi
./bin/solc solidity-cborutils=${PWD}/node_modules/solidity-cborutils/ @openzeppelin=${PWD}/node_modules/@openzeppelin/ @ensdomains=${PWD}/node_modules/@ensdomains/ contracts/v0.8/mocks/MinerAPI.sol --output-dir ./build/v0.8/mocks --overwrite --bin --hashes --opcodes --abi


deploy_simple_coin:
cd hardhat && yarn hardhat deploy --tags SimpleCoin

Expand Down
189 changes: 189 additions & 0 deletions contracts/v0.8/mocks/MarketAPI.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*******************************************************************************
* (c) 2022 Zondax AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
//
// DRAFT!! THIS CODE HAS NOT BEEN AUDITED - USE ONLY FOR PROTOTYPING
//
pragma solidity >=0.4.25 <=0.8.15;

import "../types/MarketTypes.sol";
import "./types/MockTypes.sol";

/// @title This contract is a proxy to the singleton Storage Market actor (address: f05). Calling one of its methods will result in a cross-actor call being performed. However, in this mock library, no actual call is performed.
/// @author Zondax AG
/// @dev Methods prefixed with mock_ will not be available in the real library. These methods are merely used to set mock state. Note that this interface will likely break in the future as we align it
// with that of the real library!
contract MarketAPI {
mapping(string => int256) balances;
mapping(uint64 => MockTypes.Deal) deals;

constructor() {
mock_generate_deals();
}

/// @notice Deposits the received value into the balance held in escrow.
/// @dev Because this is a mock method, no real balance is being deducted from the caller, nor incremented in the Storage Market actor (f05).
function add_balance(bytes memory provider_or_client) public payable {
balances[string(provider_or_client)] += int256(msg.value);
}

/// @notice Attempt to withdraw the specified amount from the balance held in escrow.
/// @notice If less than the specified amount is available, yields the entire available balance.
/// @dev This method should be called by an approved address, but the mock does not check that the caller is an approved party.
/// @dev Because this is a mock method, no real balance is deposited in the designated address, nor decremented from the Storage Market actor (f05).
function withdraw_balance(MarketTypes.WithdrawBalanceParams memory params) public returns (MarketTypes.WithdrawBalanceReturn memory) {
int256 tmp = balances[string(params.provider_or_client)];
if (balances[string(params.provider_or_client)] >= params.tokenAmount) {
balances[string(params.provider_or_client)] -= params.tokenAmount;
tmp = params.tokenAmount;
} else {
balances[string(params.provider_or_client)] = 0;
}

return MarketTypes.WithdrawBalanceReturn(uint256(tmp));
}

/// @return the escrow balance and locked amount for an address.
function get_balance(string memory addr) public view returns (MarketTypes.GetBalanceReturn memory) {
int256 actualBalance = balances[addr];

return MarketTypes.GetBalanceReturn(actualBalance, 0);
}

/// @return the data commitment and size of a deal proposal.
/// @notice This will be available after the deal is published (whether or not is is activated) and up until some undefined period after it is terminated.
/// @dev set data values correctly, currently returning fixed data, feel free to adjust in your local mock.
function get_deal_data_commitment(
MarketTypes.GetDealDataCommitmentParams memory params
) public view returns (MarketTypes.GetDealDataCommitmentReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealDataCommitmentReturn(bytes("0x111111"), deals[params.id].size);
}

/// @return the client of a deal proposal.
function get_deal_client(MarketTypes.GetDealClientParams memory params) public view returns (MarketTypes.GetDealClientReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealClientReturn(deals[params.id].client);
}

/// @return the provider of a deal proposal.
function get_deal_provider(
MarketTypes.GetDealProviderParams memory params
) public view returns (MarketTypes.GetDealProviderReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealProviderReturn(deals[params.id].provider);
}

/// @return the label of a deal proposal.
function get_deal_label(MarketTypes.GetDealLabelParams memory params) public view returns (MarketTypes.GetDealLabelReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealLabelReturn(deals[params.id].label);
}

/// @return the start epoch and duration (in epochs) of a deal proposal.
function get_deal_term(MarketTypes.GetDealTermParams memory params) public view returns (MarketTypes.GetDealTermReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealTermReturn(deals[params.id].start, deals[params.id].end);
}

/// @return the per-epoch price of a deal proposal.
function get_deal_total_price(
MarketTypes.GetDealEpochPriceParams memory params
) public view returns (MarketTypes.GetDealEpochPriceReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealEpochPriceReturn(deals[params.id].price_per_epoch);
}

/// @return the client collateral requirement for a deal proposal.
function get_deal_client_collateral(
MarketTypes.GetDealClientCollateralParams memory params
) public view returns (MarketTypes.GetDealClientCollateralReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealClientCollateralReturn(deals[params.id].client_collateral);
}

/// @return the provider collateral requirement for a deal proposal.
function get_deal_provider_collateral(
MarketTypes.GetDealProviderCollateralParams memory params
) public view returns (MarketTypes.GetDealProviderCollateralReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealProviderCollateralReturn(deals[params.id].provider_collateral);
}

/// @return the verified flag for a deal proposal.
/// @notice Note that the source of truth for verified allocations and claims is the verified registry actor.
function get_deal_verified(
MarketTypes.GetDealVerifiedParams memory params
) public view returns (MarketTypes.GetDealVerifiedReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealVerifiedReturn(deals[params.id].verified);
}

/// @notice Fetches activation state for a deal.
/// @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 get_deal_activation(
MarketTypes.GetDealActivationParams memory params
) public view returns (MarketTypes.GetDealActivationReturn memory) {
require(deals[params.id].id > 0);

return MarketTypes.GetDealActivationReturn(deals[params.id].activated, deals[params.id].terminated);
}

/// @notice Publish a new set of storage deals (not yet included in a sector).
function publish_storage_deals(bytes memory raw_auth_params, address callee) public {
// calls standard filecoin receiver on message authentication api method number
(bool success, ) = callee.call(
abi.encodeWithSignature("handle_filecoin_method(uint64,uint64,bytes)", 0, 2643134072, raw_auth_params)
);
require(success, "client contract failed to authorize deal publish");
}

/// @notice Adds mock deal data to the internal state of this mock.
/// @dev Feel free to adjust the data here to make it align with deals in your network.
function mock_generate_deals() internal {
MockTypes.Deal memory deal_67;
deal_67.id = 67;
deal_67.cid = "baga6ea4seaqlkg6mss5qs56jqtajg5ycrhpkj2b66cgdkukf2qjmmzz6ayksuci";
deal_67.size = 8388608;
deal_67.verified = false;
deal_67.client = "t01109";
deal_67.provider = "t01113";
deal_67.label = "mAXCg5AIg8YBXbFjtdBy1iZjpDYAwRSt0elGLF5GvTqulEii1VcM";
deal_67.start = 25245;
deal_67.end = 545150;
deal_67.price_per_epoch = 1100000000000;
deal_67.provider_collateral = 0;
deal_67.client_collateral = 0;
deal_67.activated = 1;
deal_67.terminated = 0;

deals[deal_67.id] = deal_67;

// As EVM smart contract has a limited capacity for size (24KiB), we cannot set all deals directly here.
// Please, take them from docs.

// Add or replace more deals here.
}
}
117 changes: 117 additions & 0 deletions contracts/v0.8/mocks/MinerAPI.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*******************************************************************************
* (c) 2022 Zondax AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
//
// DRAFT!! THIS CODE HAS NOT BEEN AUDITED - USE ONLY FOR PROTOTYPING
//
pragma solidity >=0.4.25 <=0.8.15;

import "../types/MinerTypes.sol";

/// @title This contract is a proxy to a built-in Miner actor. Calling one of its methods will result in a cross-actor call being performed. However, in this mock library, no actual call is performed.
/// @author Zondax AG
/// @dev Methods prefixed with mock_ will not be available in the real library. These methods are merely used to set mock state. Note that this interface will likely break in the future as we align it
// with that of the real library!
contract MinerAPI {
bytes owner;
bool isBeneficiarySet = false;
CommonTypes.ActiveBeneficiary activeBeneficiary;
mapping(CommonTypes.SectorSize => uint64) sectorSizesBytes;

/// @notice (Mock method) Sets the owner of a Miner on contract deployment, which will be returned via get_owner().
constructor(bytes memory _owner) {
owner = _owner;

sectorSizesBytes[CommonTypes.SectorSize._2KiB] = 2 << 10;
sectorSizesBytes[CommonTypes.SectorSize._8MiB] = 8 << 20;
sectorSizesBytes[CommonTypes.SectorSize._512MiB] = 512 << 20;
sectorSizesBytes[CommonTypes.SectorSize._32GiB] = 32 << 30;
sectorSizesBytes[CommonTypes.SectorSize._64GiB] = 2 * (32 << 30);
}

/// @notice (Mock method) Sets the owner of a Miner, which will be returned via get_owner().
function mock_set_owner(bytes memory addr) public {
require(owner.length == 0);
owner = addr;
}

/// @notice Income and returned collateral are paid to this address
/// @notice This address is also allowed to change the worker address for the miner
/// @return the owner address of a Miner
function get_owner() public view returns (MinerTypes.GetOwnerReturn memory) {
require(owner.length != 0);

return MinerTypes.GetOwnerReturn(owner);
}

/// @param addr New owner address
/// @notice Proposes or confirms a change of owner address.
/// @notice If invoked by the current owner, proposes a new owner address for confirmation. If the proposed address is the current owner address, revokes any existing proposal that proposed address.
function change_owner_address(bytes memory addr) public {
owner = addr;
}

/// @param params The "controlling" addresses are the Owner, the Worker, and all Control Addresses.
/// @return Whether the provided address is "controlling".
function is_controlling_address(
MinerTypes.IsControllingAddressParam memory params
) public pure returns (MinerTypes.IsControllingAddressReturn memory) {
return MinerTypes.IsControllingAddressReturn(false);
}

/// @return the miner's sector size.
function get_sector_size() public view returns (MinerTypes.GetSectorSizeReturn memory) {
return MinerTypes.GetSectorSizeReturn(sectorSizesBytes[CommonTypes.SectorSize._8MiB]);
}

/// @notice This is calculated as actor balance - (vesting funds + pre-commit deposit + initial pledge requirement + fee debt)
/// @notice Can go negative if the miner is in IP debt.
/// @return the available balance of this miner.
function get_available_balance() public pure returns (MinerTypes.GetAvailableBalanceReturn memory) {
return MinerTypes.GetAvailableBalanceReturn(10000000000000000000000);
}

/// @return the funds vesting in this miner as a list of (vesting_epoch, vesting_amount) tuples.
function get_vesting_funds() public pure returns (MinerTypes.GetVestingFundsReturn memory) {
CommonTypes.VestingFunds[] memory vesting_funds = new CommonTypes.VestingFunds[](1);
vesting_funds[0] = CommonTypes.VestingFunds(1668514825, 2000000000000000000000);

return MinerTypes.GetVestingFundsReturn(vesting_funds);
}

/// @notice Proposes or confirms a change of beneficiary address.
/// @notice A proposal must be submitted by the owner, and takes effect after approval of both the proposed beneficiary and current beneficiary, if applicable, any current beneficiary that has time and quota remaining.
/// @notice See FIP-0029, https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0029.md
function change_beneficiary(MinerTypes.ChangeBeneficiaryParams memory params) public {
if (!isBeneficiarySet) {
CommonTypes.BeneficiaryTerm memory term = CommonTypes.BeneficiaryTerm(params.new_quota, 0, params.new_expiration);
activeBeneficiary = CommonTypes.ActiveBeneficiary(params.new_beneficiary, term);
isBeneficiarySet = true;
} else {
activeBeneficiary.beneficiary = params.new_beneficiary;
activeBeneficiary.term.quota = params.new_quota;
activeBeneficiary.term.expiration = params.new_expiration;
}
}

/// @notice This method is for use by other actors (such as those acting as beneficiaries), and to abstract the state representation for clients.
/// @notice Retrieves the currently active and proposed beneficiary information.
function get_beneficiary() public view returns (MinerTypes.GetBeneficiaryReturn memory) {
require(isBeneficiarySet);

CommonTypes.PendingBeneficiaryChange memory proposed;
return MinerTypes.GetBeneficiaryReturn(activeBeneficiary, proposed);
}
}
40 changes: 40 additions & 0 deletions contracts/v0.8/mocks/types/MockTypes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*******************************************************************************
* (c) 2022 Zondax AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
//
// DRAFT!! THIS CODE HAS NOT BEEN AUDITED - USE ONLY FOR PROTOTYPING
//
pragma solidity >=0.4.25 <=0.8.15;

/// @title Filecoin market actor types for Solidity.
/// @author Zondax AG
library MockTypes {
struct Deal {
uint64 id;
bytes cid;
uint64 size;
bool verified;
bytes client;
bytes provider;
string label;
int64 start;
int64 end;
uint256 price_per_epoch;
uint256 provider_collateral;
uint256 client_collateral;
int64 activated;
int64 terminated;
}
}
4 changes: 4 additions & 0 deletions docs/api/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "API",
"position": 4
}
Loading

0 comments on commit 844836d

Please sign in to comment.