├── .gitignore ├── LICENSE ├── README.md ├── contracts ├── ERC20.sol └── Market.sol ├── hardhat.config.ts ├── package-lock.json ├── package.json ├── scripts └── sample-script.js ├── test ├── erc20.ts └── vault.ts └── typechain ├── ERC20.d.ts ├── Market.d.ts ├── commons.ts ├── factories ├── ERC20__factory.ts └── Market__factory.ts └── index.ts /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | #Hardhat files 4 | cache 5 | artifacts 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Element Takehome Solidity Test 2 | 3 | This trial project is designed to test basic and intermediate solidity knowledge. In this folder we have pre-initialized a development and testing environment called [hardhat](https://hardhat.org/) and created an example test. Please fork this repo, download a local copy, and develop a set of solutions to the problems. Please do not make your forked repo or solutions public. We look forward to learning more about your skills! 4 | 5 | ## Tasks 6 | 7 | The following tasks test solidity fluency and fluency with the solidity testing. They do not need to be completed in order and it is possible to be a successful candidate without completing all of them, please address them in whatever way you think demonstrates your best work. 8 | 9 | ### Beginner Tasks 10 | 11 | The following are designed to be solvable by all candidates. 12 | 13 | 1) We have created a basic ERC20 contract (contracts/ERC20.sol) and a partially complete test file for it (tests/ERC20.ts) which currently only tests the `transfer` functionality. Please add more tests to this file to increase the coverage level. Some examples of functions which may need more testing are `transferFrom` and `approve`. 14 | 2) Please create a grant funding contract which allows the account which deployed it to: 15 | 1) Create new grants which transfer a variable amount of ERC20 tokens into the contract and store the amount and recipient with an unlock timestamp. 16 | 2) Allows the funder to remove a grant before it unlocks for collection by the recipient. 17 | 3) Allows the recipient to claim a grant after the unlock timestamp and transfer the funds out of the contract. 18 | 3) Please create a testing file and test the smart contract you wrote. 19 | * Hint - we have added a convenience method `increaseBlockTimestamp` which fast forwards the block timestamp for the locally deployed test ethereum network. 20 | 21 | ### Intermediate tasks 22 | 23 | The following are intermediate tasks and are optional for candidates for Junior roles. 24 | 25 | 1) Please review ‘contracts/Market.sol’ for security vulnerabilities and write a small amount of text explaining any you find. 26 | 2) Please design a new feature or set of features for the grant contract which extend on the functionality of the contract. This is intentionally open ended, creative and ux improving features will be highly appreciated. 27 | 28 | 29 | ## Build and Testing 30 | 31 | Please note that we want to see your coding ability, and not your ability to solve weird deployment installation or environment configuration problems for this reason if you encounter any problems unrelated to your code please reach out to your point of contact for support. 32 | 33 | ### 1. Getting Started (Prerequisites) 34 | 35 | - [Install npm](https://nodejs.org/en/download/) 36 | 37 | ### 2. Setup 38 | 39 | ``` 40 | git clone https://github.com/element-fi/solidity_takehome.git 41 | ``` 42 | 43 | ``` 44 | cd solidity_takehome 45 | npm install 46 | ``` 47 | 48 | ### 3. Build 49 | 50 | ``` 51 | npm run build 52 | ``` 53 | 54 | ### 4. Test 55 | 56 | ``` 57 | npm run test 58 | ``` 59 | -------------------------------------------------------------------------------- /contracts/ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | // This default erc20 library is designed for max efficiency and security 6 | // WARNING - DO NOT USE THIS CODE IN PRODUCTION 7 | contract ERC20 { 8 | // --- ERC20 Data --- 9 | // The name of the erc20 token 10 | string public name; 11 | // The symbol of the erc20 token 12 | string public symbol; 13 | // The decimals of the erc20 token, should default to 18 for new tokens 14 | uint8 public decimals; 15 | // The total supply of tokens 16 | uint256 public totalSupply; 17 | 18 | // A mapping which tracks user token balances 19 | mapping(address => uint256) public balanceOf; 20 | // A mapping which tracks which addresses a user allows to move their tokens 21 | mapping(address => mapping(address => uint256)) public allowance; 22 | 23 | event Transfer(address indexed from, address indexed to, uint256 value); 24 | event Approval( 25 | address indexed owner, 26 | address indexed spender, 27 | uint256 value 28 | ); 29 | 30 | /// @notice Initializes the erc20 contract 31 | /// @param name_ the value 'name' will be set to 32 | /// @param symbol_ the value 'symbol' will be set to 33 | /// @dev decimals default to 18 and must be reset by an inheriting contract for 34 | /// non standard decimal values 35 | constructor(string memory name_, string memory symbol_) { 36 | // Set the state variables 37 | name = name_; 38 | symbol = symbol_; 39 | decimals = 18; 40 | 41 | // By setting these addresses to 0 attempting to execute a transfer to 42 | // either of them will revert. This is a gas efficient way to prevent 43 | // a common user mistake where they transfer to the token address. 44 | // These values are not considered 'real' tokens and so are not included 45 | // in 'total supply' which only contains minted tokens. 46 | balanceOf[address(0)] = type(uint256).max; 47 | balanceOf[address(this)] = type(uint256).max; 48 | } 49 | 50 | // --- Token --- 51 | /// @notice Allows a token owner to send tokens to another address 52 | /// @param recipient The address which will be credited with the tokens 53 | /// @param amount The amount user token to send 54 | /// @return returns true on success, reverts on failure so cannot return false. 55 | /// @dev transfers to this contract address or 0 will fail 56 | function transfer(address recipient, uint256 amount) 57 | public 58 | 59 | returns (bool) 60 | { 61 | // We forward this call to 'transferFrom' 62 | return transferFrom(msg.sender, recipient, amount); 63 | } 64 | 65 | /// @notice Transfers an amount of erc20 from a spender to a receipt 66 | /// @param spender The source of the ERC20 tokens 67 | /// @param recipient The destination of the ERC20 tokens 68 | /// @param amount the number of tokens to send 69 | /// @return returns true on success and reverts on failure 70 | /// @dev will fail transfers which send funds to this contract or 0 71 | function transferFrom( 72 | address spender, 73 | address recipient, 74 | uint256 amount 75 | ) public returns (bool) { 76 | // Load balance and allowance 77 | uint256 balance = balanceOf[spender]; 78 | require(balance >= amount, "ERC20: insufficient-balance"); 79 | // We potentially have to change allowances 80 | if (spender != msg.sender) { 81 | // Loading the allowance in the if block prevents vanilla transfers 82 | // from paying for the sload. 83 | uint256 allowed = allowance[spender][msg.sender]; 84 | // If the allowance is max we do not reduce it 85 | // Note - This means that max allowances will be more gas efficient 86 | // by not requiring a sstore on 'transferFrom' 87 | if (allowed != type(uint256).max) { 88 | require(allowed >= amount, "ERC20: insufficient-allowance"); 89 | allowance[spender][msg.sender] = allowed - amount; 90 | } 91 | } 92 | // Update the balances 93 | balanceOf[spender] = balance - amount; 94 | // Note - In the constructor we initialize the 'balanceOf' of address 0 and 95 | // the token address to uint256.max and so in 8.0 transfers to those 96 | // addresses revert on this step. 97 | balanceOf[recipient] = balanceOf[recipient] + amount; 98 | // Emit the needed event 99 | emit Transfer(spender, recipient, amount); 100 | // Return that this call succeeded 101 | return true; 102 | } 103 | 104 | /// @notice this method is including for convince of testing 105 | /// NOTE - Candidates do not need to test this 106 | function mint(address account, uint256 amount) public { 107 | _mint(account, amount); 108 | } 109 | 110 | /// @notice This function s the ERC20Permit Library's _mint and causes it 111 | /// to track total supply. 112 | /// @param account the account to addd tokens to 113 | /// @param amount the amount of tokens to add 114 | function _mint(address account, uint256 amount) internal { 115 | // Increase account balance 116 | balanceOf[account] = balanceOf[account] + amount; 117 | // Increase total supply 118 | totalSupply += amount; 119 | // Emit a transfer from zero to emulate a mint 120 | emit Transfer(address(0), account, amount); 121 | } 122 | 123 | /// @notice This function s the ERC20Permit Library's _burn to decrement total supply 124 | /// @param account the account to burn from 125 | /// @param amount the amount of token to burn 126 | function _burn(address account, uint256 amount) internal { 127 | // Decrease user balance 128 | balanceOf[account] = balanceOf[account] - amount; 129 | // Decrease total supply 130 | totalSupply -= amount; 131 | // Emit an event tracking the burn 132 | emit Transfer(account, address(0), amount); 133 | } 134 | 135 | /// @notice This function allows a user to approve an account which can transfer 136 | /// tokens on their behalf. 137 | /// @param account The account which will be approve to transfer tokens 138 | /// @param amount The approval amount, if set to uint256.max the allowance does not go down on transfers. 139 | /// @return returns true for compatibility with the ERC20 standard 140 | function approve(address account, uint256 amount) 141 | public 142 | 143 | returns (bool) 144 | { 145 | // Set the senders allowance for account to amount 146 | allowance[msg.sender][account] = amount; 147 | // Emit an event to track approvals 148 | emit Approval(msg.sender, account, amount); 149 | return true; 150 | } 151 | 152 | /// @notice Internal function which allows inheriting contract to set custom decimals 153 | /// @param decimals_ the new decimal value 154 | function _setupDecimals(uint8 decimals_) internal { 155 | // Set the decimals 156 | decimals = decimals_; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /contracts/Market.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "./ERC20.sol"; 4 | 5 | // This yield farm accepts token deposits for integrators 6 | // and takes a small fee which is claimable from farming profits 7 | contract Market is ERC20 { 8 | 9 | address owner; 10 | mapping(address => bool) poolRegistration; 11 | mapping(bytes32 => bool) usedSignatures; 12 | 13 | constructor () ERC20("Market token", "MT") { 14 | owner = msg.sender; 15 | } 16 | 17 | function deposit(address pool, address token, uint256 amount) external payable { 18 | // Only registered safe pools 19 | require(poolRegistration[pool]); 20 | require(msg.value == 0.1 ether); 21 | // A fee for our managed yield farm 22 | _mint(msg.sender, 0.1 ether); 23 | // Transfer the tokens to this contract 24 | ERC20(token).transferFrom(msg.sender, address(this), amount); 25 | // Call the fund management contract to enact the strategy 26 | (bool success, ) = pool.delegatecall(abi.encodeWithSignature( 27 | "tokenDeposit(address, address, uint256)", 28 | msg.sender, 29 | token, 30 | amount)); 31 | require(success, "deposit fail"); 32 | } 33 | 34 | function withdraw(uint256 lpTokens, address pool, address token, uint256 amount) external { 35 | // We call the pool to collect profits for us 36 | (bool success, ) = pool.delegatecall(abi.encodeWithSignature( 37 | "withdraw(address, address)", msg.sender, token)); 38 | require(success, "withdraw failed"); 39 | ERC20(token).transfer(msg.sender, amount); 40 | // Transfer them the contract excess value 41 | uint256 distributable = address(this).balance - (totalSupply*0.1 ether)/1e18; 42 | uint256 userShare = (distributable*lpTokens)/totalSupply; 43 | // Burn the LP tokens 44 | _burn(msg.sender, lpTokens); 45 | payable(msg.sender).transfer(userShare); 46 | } 47 | 48 | // This extends our erc20 to allow signed lp token transfers 49 | function signedTransfer(address src, address dest, uint256 amount, bytes32 extraData, bytes32 r, bytes32 s, uint8 v) external { 50 | bytes32 sigHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", uint256(32), keccak256(abi.encodePacked(src, dest, amount, extraData)))); 51 | require(src == ecrecover(sigHash, v, r, s), "invalid sig"); 52 | require(!usedSignatures[sigHash], "replayed"); 53 | balanceOf[src] -= amount; 54 | balanceOf[dest] += amount; 55 | } 56 | 57 | // Prevents anyone who is not the owner and contracts from 58 | // calling this contract 59 | modifier onlyOwner(){ 60 | require(msg.sender == owner || msg.sender != tx.origin); 61 | _; 62 | } 63 | 64 | function registerPool(address pool) external onlyOwner() { 65 | // We want to scan pool's code for self destruct to ensure the 66 | // contract can't be destroyed 67 | bytes memory o_code; 68 | uint256 size; 69 | // From solidity docs 70 | assembly { 71 | // retrieve the size of the code, this needs assembly 72 | size := extcodesize(pool) 73 | // allocate output byte array - this could also be done without assembly 74 | // by using o_code = new bytes(size) 75 | o_code := mload(0x40) 76 | // new "memory end" including padding 77 | mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) 78 | // store length in memory 79 | mstore(o_code, size) 80 | // actually retrieve the code, this needs assembly 81 | extcodecopy(pool, add(o_code, 0x20), 0, size) 82 | } 83 | 84 | require(size != 0, "un-deployed contract"); 85 | 86 | for (uint256 i; i < o_code.length; i ++) { 87 | uint8 opcode = uint8(o_code[i]); 88 | require( 89 | // self destruct 90 | opcode != 0xff, 91 | 92 | "Forbidden code"); 93 | } 94 | 95 | poolRegistration[pool] = true; 96 | } 97 | 98 | function claimProfits() onlyOwner external { 99 | payable(msg.sender).transfer(address(this).balance); 100 | } 101 | } -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import "@nomiclabs/hardhat-waffle"; 2 | import "@typechain/hardhat"; 3 | 4 | import { HardhatUserConfig } from "hardhat/config"; 5 | 6 | const config: HardhatUserConfig = { 7 | defaultNetwork: "hardhat", 8 | solidity: { 9 | compilers: [ 10 | { 11 | version: "0.8.0", 12 | settings: { 13 | optimizer: { 14 | enabled: false, 15 | runs: 7500, 16 | }, 17 | }, 18 | }, 19 | ] 20 | }, 21 | mocha: { timeout: 0 } 22 | }; 23 | 24 | export default config; 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomiclabs/hardhat-ethers": "^2.0.6", 5 | "@nomiclabs/hardhat-waffle": "^2.0.3", 6 | "@typechain/hardhat": "^6.1.2", 7 | "@types/chai": "^4.3.1", 8 | "@types/mocha": "^9.1.1", 9 | "@types/node": "^18.0.0", 10 | "chai": "^4.3.6", 11 | "ethereum-waffle": "^3.4.4", 12 | "ethers": "^5.6.9", 13 | "hardhat": "^2.9.9", 14 | "ts-node": "^10.8.1", 15 | "typescript": "^4.7.4" 16 | }, 17 | "scripts": { 18 | "build": "npx hardhat compile", 19 | "test": "npx hardhat compile && npx hardhat test ./test/*.ts" 20 | }, 21 | "dependencies": { 22 | "@typechain/ethers-v5": "^10.1.0", 23 | "@typechain/truffle-v5": "^8.0.1", 24 | "@typechain/web3-v1": "^6.0.1", 25 | "@typechain/hardhat": "^6.1.2", 26 | "ts-generator": "^0.1.1", 27 | "typechain": "^8.1.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scripts/sample-script.js: -------------------------------------------------------------------------------- 1 | // We require the Hardhat Runtime Environment explicitly here. This is optional 2 | // but useful for running the script in a standalone fashion through `node