Package: smart-contracts-for-testing
Mock smart contracts for writing Ethereum test suitesThis package contains common Ethereum smart contracts to be used in automated test suites.
This was created forTrading Strategy, but can be used for any other
projects as well. As opposite to slower and messiermainnet forking test strategies,
this project aims to explicit clean deployments and very fast test execution.Smart contract support includesERC-20 tokenSushiSwap: router, factory, pool (Uniswap v2, PancakeSwape, QuickSwap, Trader Joe and others are 99% Sushiswap compatible)High-quality API documentationFull type hinting support for optimal developer experience(More integrations to come)Table of contentsPrecompiled ABI file distributionPython usagePrerequisitesERC-20 token exampleUniswap swap exampleHow to use hhe library in your Python projectDevelopmentRequiresMakeVersion historyDiscordNotesLicensePrecompiled ABI file distributionThis package primarly supports Python, Web3.p3 and Brownie developers.
For other programming languages and frameworks,
you canfind precompiled Solidity smart contracts in abi folder.These files are good to go with any framework:Web3.jsEthers.jsHardhatTruffleWeb3jEach JSON file hasabiandbytecodekeys you need to deploy a contract.Just download and embed in your project.
The compiled source code files are mixture of MIT and GPL v2 license.Python usageThe Python support is available assmart_contract_test_fixturesPython package.The package depends only onweb3.pyand not others, like Brownie.
It grabs popular ABI files with their bytecode and compilation artifacts so that the contracts
are easily deployable on any Ethereum tester interface. No Ganache is needed and everything
can be executed on fastereth-tester enginer.PrerequisitesProficient in Python programmingUnderstanding of Web3.py librarypytest basicsERC-20 token exampleTo use the package to deploy a simple ERC-20 token inpytesttesting:importpytestfromweb3importWeb3,EthereumTesterProviderfromsmart_contracts_for_testing.tokenimportcreate_token@pytest.fixturedeftester_provider():returnEthereumTesterProvider()@pytest.fixturedefeth_tester(tester_provider):returntester_provider.ethereum_tester@pytest.fixturedefweb3(tester_provider):returnWeb3(tester_provider)@pytest.fixture()defdeployer(web3)->str:"""Deploy account."""returnweb3.eth.accounts[0]@pytest.fixture()defuser_1(web3)->str:"""User account."""returnweb3.eth.accounts[1]@pytest.fixture()defuser_2(web3)->str:"""User account."""returnweb3.eth.accounts[2]deftest_deploy_token(web3:Web3,deployer:str):"""Deploy mock ERC-20."""token=create_token(web3,deployer,"Hentai books token","HENTAI",100_000*10**18)asserttoken.functions.name().call()=="Hentai books token"asserttoken.functions.symbol().call()=="HENTAI"asserttoken.functions.totalSupply().call()==100_000*10**18asserttoken.functions.decimals().call()==18deftest_tranfer_tokens_between_users(web3:Web3,deployer:str,user_1:str,user_2:str):"""Transfer tokens between users."""token=create_token(web3,deployer,"Telos EVM rocks","TELOS",100_000*10**18)# Move 10 tokens from deployer to user1token.functions.transfer(user_1,10*10**18).transact({"from":deployer})asserttoken.functions.balanceOf(user_1).call()==10*10**18# Move 10 tokens from deployer to user1token.functions.transfer(user_2,6*10**18).transact({"from":user_1})asserttoken.functions.balanceOf(user_1).call()==4*10**18asserttoken.functions.balanceOf(user_2).call()==6*10**18See full example.For more information how to user Web3.py in testing, see Web3.py documentation.Uniswap swap exampleimportpytestfromweb3importWeb3fromweb3.contractimportContractfromsmart_contracts_for_testing.uniswap_v2importUniswapV2Deployment,deploy_trading_pair,FOREVER_DEADLINEdeftest_swap(web3:Web3,deployer:str,user_1:str,uniswap_v2:UniswapV2Deployment,weth:Contract,usdc:Contract):"""User buys WETH on Uniswap v2 using mock USDC."""# Create the trading pair and add initial liquiditydeploy_trading_pair(web3,deployer,uniswap_v2,weth,usdc,10*10**18,# 10 ETH liquidity17_000*10**18,# 17000 USDC liquidity)router=uniswap_v2.router# Give user_1 500 dollars to buy ETH and approve it on the routerusdc_amount_to_pay=500*10**18usdc.functions.transfer(user_1,usdc_amount_to_pay).transact({"from":deployer})usdc.functions.approve(router.address,usdc_amount_to_pay).transact({"from":user_1})# Perform a swap USDC->WETHpath=[usdc.address,weth.address]# Path tell how the swap is routed# https://docs.uniswap.org/protocol/V2/reference/smart-contracts/router-02#swapexacttokensfortokensrouter.functions.swapExactTokensForTokens(usdc_amount_to_pay,0,path,user_1,FOREVER_DEADLINE,).transact({"from":user_1})# Check the user_1 received ~0.284 ethersassertweth.functions.balanceOf(user_1).call()/1e18==pytest.approx(0.28488156127668085)See the full example.How to use hhe library in your Python projectAddsmart_contract_test_fixturesas a development dependency:UsingPoetry:poetryadd-Dsmart_contract_test_fixturesDevelopmentThis step will extract compiled smart contract from Sushiswap repository.RequiresNode v14npxyarnGNU MakeUnix shellMakeTo build the ABI distribution:gitsubmoduleupdate--recursive--init
makeallSee SushiSwap continuous integration files for more information.Version historySee change log.DiscordJoin Discord for any questions.NotesCurrently there is noBrowniesupport.
To support Brownie, one would need to figure out how to import an existing Hardhat
based project (Sushiswap) to Brownie project format.LicenseMIT