gnosis / mock-contract Goto Github PK
View Code? Open in Web Editor NEWSimple Solidity contract to mock dependent contracts in truffle tests.
Simple Solidity contract to mock dependent contracts in truffle tests.
Hi, I am trying to simulate a call to UniswapV2Router02.swapExactETHForTokens() (link)
That method returns a uint[], so I tried mocking that using: abi.rawEncode([ "uint[]" ], [ [1] ])
Here is the complete method mock definition:
await uniswapV2Router02.givenMethodReturn(
uniswapEncorder.encodeRouterETHForTokens(),
abi.rawEncode([ "uint[]" ], [ [1] ])
);
Is it possible to encode an array of values?
Thanks!
Background
The Gnosis MockContract is a smart contract enabling developers to quickly mock contract interactions for unit tests.
It enables developers to
The MockContract facilitates these features without requiring any separate test contracts.
Check out the repo: https://github.com/gnosis/mock-contract
Task
Extend the functionality of the MockContract to partially matching arguments.
Acceptance criteria
const particallyMatchedCalldata = contract.methods.methodName(
accounts[0], ANY, ..., ANY
).encodeABI()
Here, ANY would be some sort of constant defined in the smart contract.
function givenPartialCalldataReturn(bytes calldata call, bytes calldata response) external;
function givenPartialCalldataReturnBool(bytes calldata call, bool response) external;
function givenPartialCalldataReturnUint(bytes calldata call, uint response) external;
function givenPartialCalldataReturnAddress(bytes calldata call, address response) external;
function givenPartialCalldataRevert(bytes calldata call) external;
function givenPartialCalldataRevertWithMessage(bytes calldata call, string calldata message) external;
function givenPartialCalldataRunOutOfGas(bytes calldata call) external;
They should enable the same functionality on partially matching calldata as the current respective functions with the same function names, but without the word "Partial".
function invocationCount() external returns (uint);
function invocationCountForMethod(bytes calldata method) external returns (uint);
function invocationCountForCalldata(bytes calldata call) external returns (uint);
Payout:
0.5 ETH
Additional GNO can be tipped according to the level of technical implementation
The example given in the README tutorial for Mocking Methods Individually
token.contract.transferFrom.getData(0, 0, 0)
doesn't seen to work.
The following seems to remedy this.
token.contract.methods.transferFrom(0, 0, 0).encodeABI();
taken from here
Version Info:
Truffle v5.0.8 (core: 5.0.8)
Solidity - ^0.5.0 (solc-js)
Node v11.12.0
Web3.js v1.0.0-beta.37
I am using your library to test a smart contract that requires another one. I am also using npx hardhat test test/simpleTest.ts
for testing. I am not sure if this is a bug or just me doing something I shouldn't. Here is my code for test/simpleTest.ts:
import { MockContractInstance, PChainStakeMirrorVerifierInstance, PChainStakeMirrorVerifierMockInstance } from "../../../../typechain-truffle";
import type { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { BN } from "bn.js";
import { ethers } from 'hardhat';
import { abi } from "../artifacts/contracts/Random.sol/Random.json"
import { RandomContract, RouletteContract, RouletteInstance } from '../typechain-types/';
import { RandomInstance } from "../typechain-types/contracts/Random";
const MockContract = artifacts.require("MockContract");
const Roulette: RouletteContract = artifacts.require('Roulette');
const Random: RandomInstance = artifacts.require('Random');
function bn(n: any) {
return new BN(n.toString());
}
const IRandom = new web3.eth.Contract(
abi as any
)
describe('Roulette', async () => {
let roulette: RouletteInstance
let owner: SignerWithAddress
let randomMock: MockContractInstance
beforeEach(async () => {
randomMock = await MockContract.new();
const methodGetRandom = IRandom.methods.getRandom(25).encodeABI()
// await ethers.getSigners();
[owner] = await ethers.getSigners();
randomMock.givenCalldataReturn(
methodGetRandom,
web3.eth.abi.encodeParameters(["uint256", "bool"], [12345 , true])
)
console.log(owner);
})
})
This code produces TypeError: Cannot create property 'undefined' on string '0xcd4b69140000000000000000000000000000000000000000000000000000000000000019'
. If I uncomment // await ethers.getSigners();
, it works.
If I move randomMock... above getting owner, then owner is undefined. Again uncommenting that await ... line makes it work again.
I hope either I am doing something wrong or it helps you improve your library. If you need more information I can provide it.
I'm trying to use mock-contract
and getting the following error:
Steps Iv'e taken:
"@gnosis.pm/mock-contract": "^3.0.8",
to my package.json
(and of course ran npm i
)Imports.sol
to my contracts
folder with the following contents:pragma solidity ^0.5.0;
// We import the contract so truffle compiles it, and we have the ABI
// available when working from truffle console.
import "@gnosis.pm/mock-contract/contracts/MockContract.sol";
settings.json
file: "solidity.packageDefaultDependenciesContractsDirectory": "",
"solidity.packageDefaultDependenciesDirectory": "node_modules"
const MockContract = artifacts.require("./MockContract.sol");
to the top of my test file.@fleupold (or anyone else) are you able to tell me what the problem is?
By the way I just want to mention that I really appreciate that you built this. From what I can find, its the only smart contract mocking framework around. The only other alternativeseems to be just writing fake contracts which I really prefer not to do.
Should we add support for solidity 0.6?
After upgrading to Sol 0.5.0
, tests making multiple calls to view functions in a single transaction began failing. I brought this up to @fleupold who determined that it's a gas issue with updateInvocationCount
Turns out that it's a gas issue. https://github.com/gnosis/mock-contract/blob/master/contracts/MockContract.sol#L374 get's forwarded all but 1/64th of the gas and since it throws an exception when called in a view's function context that gas is used. This means there is only very little gas left for the remaining code. Having three of those reverts in a row seems to exceeds the gas limit provided by truffle. The fix would be to change the .call(abi.encodeWithSignature("update... to .call.gas(100000)(abi...
I'll be opening a PR for this shortly with a test that was previously failing.
I am trying to set up a mock return tuple. Is it possible to do something like:
const finalizePriceEpoch = ftsoInterface.contract.methods.finalizePriceEpoch(0, true);
const finalizePriceEpochReturn = web3.eth.abi.encodeParameters(
["address[]", "uint64[]", "uint256"],
[[], [], "0"]);
await mockFtso.givenMethodReturn(finalizePriceEpoch, finalizePriceEpochReturn);
With the above, I get this error when calling givenMethodReturn:
1) Contract: RewardManager.sol; test/unit/implementations/RewardManager.js; Reward manager unit tests
Should finalize price epoch for winning ftso with no reward recipients:
Error: invalid arrayify value (argument="value", value="[object Object]", code=INVALID_ARGUMENT, version=bytes/5.0.11)
Love this mock contract and how carefully it's been designed, not to mention a well-written README :)
I noticed you guys have upgraded to solidity 0.6 but have not put the package on NPM. Any reason not to update it now?
Thanks!
In Solidity 0.5.0 view functions are called via STATICCALL
which disallows state modifications. MockContract
's fallback function modifies state which causes mocked view functions to revert. Here's an example test that demonstrates this.
Update: When commenting out invocation recording the test passes.
The version on NPM is two years old. It still uses solidity 0.6.0 instead of 0.8.0 which is supported in the latest version on the master
branch.
Background
The Gnosis MockContract is a smart contract enabling developers to quickly mock contract interactions for unit tests.
It enables developers to
The MockContract facilitates these features without requiring any separate test contracts. Check out the repo: https://github.com/gnosis/mock-contract
Task
Extend the functionality of the MockContract to mock contract interaction on calldata with predicate
s
Acceptance criteria:
const calldata = contract.methods.foo(
GREATER_THAN(10)
).encodeABI()
and the predicate SMALL_THAN
const calldata = contract.methods.foo(
SMALLER_THAN(10)
).encodeABI()
function givenPredicateCalldataReturn(bytes calldata call, bytes calldata response) external;
function givenPredicateCalldataReturnBool(bytes calldata call, bool response) external;
function givenPredicateCalldataReturnUint(bytes calldata call, uint response) external;
function givenPredicateCalldataReturnAddress(bytes calldata call, address response) external;
function givenPredicateCalldataRevert(bytes calldata call) external;
function givenPredicateCalldataRevertWithMessage(bytes calldata call, string calldata message) external;
function givenPredicateCalldataRunOutOfGas(bytes calldata call) external;
They should enable the same functionality on calldata with predicates as the current respective
functions with the same function names, but without the word "Predicate".
function invocationCount() external returns (uint);
function invocationCountForMethod(bytes calldata method) external returns (uint);
function invocationCountForCalldata(bytes calldata call) external returns (uint);
Payout:
0.75 ETH
Additional GNO can be tipped according to the level of technical implementation
E.g. add something similar to
function exec(address payable to, uint256 value, bytes calldata data) external {
bool success;
bytes memory response;
(success,response) = to.call{value: value}(data);
if(!success) {
assembly {
revert(add(response, 0x20), mload(response))
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.