-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
📦 Introduce subpackage for Proof Of Reserve feature development (#1189)
Co-authored-by: Michał Sieczkowski <michal.sieczkowski@trusttoken.com>
- Loading branch information
Showing
15 changed files
with
2,360 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
packages/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"version": "0.8.16", | ||
"settings": { | ||
"optimizer": { | ||
"enabled": true, | ||
"runs": 200 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/node_modules | ||
/build | ||
/cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"require": ["ts-node/register/transpile-only", "tsconfig-paths/register"], | ||
"extension": ["ts"], | ||
"target": "esnext", | ||
"timeout": 40000, | ||
"watch-files": ["test"], | ||
"exit": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
const fs = require('fs') | ||
const path = require('path') | ||
const { extendConfig } = require('hardhat/config') | ||
|
||
const { HardhatPluginError } = require('hardhat/plugins') | ||
|
||
const { | ||
TASK_COMPILE, | ||
} = require('hardhat/builtin-tasks/task-names') | ||
|
||
extendConfig(function (config, userConfig) { | ||
config.abiExporter = Object.assign( | ||
{ | ||
path: './abi', | ||
clear: false, | ||
flat: false, | ||
only: [], | ||
except: [], | ||
spacing: 2, | ||
}, | ||
userConfig.abiExporter, | ||
) | ||
}) | ||
|
||
task(TASK_COMPILE, async function (args, hre, runSuper) { | ||
const config = hre.config.abiExporter | ||
|
||
await runSuper() | ||
|
||
const outputDirectory = path.resolve(hre.config.paths.root, config.path) | ||
|
||
if (!outputDirectory.startsWith(hre.config.paths.root)) { | ||
throw new HardhatPluginError('resolved path must be inside of project directory') | ||
} | ||
|
||
if (outputDirectory === hre.config.paths.root) { | ||
throw new HardhatPluginError('resolved path must not be root directory') | ||
} | ||
|
||
if (config.clear) { | ||
if (fs.existsSync(outputDirectory)) { | ||
fs.rmdirSync(outputDirectory, { recursive: true }) | ||
} | ||
} | ||
|
||
if (!fs.existsSync(outputDirectory)) { | ||
fs.mkdirSync(outputDirectory, { recursive: true }) | ||
} | ||
|
||
for (const fullName of await hre.artifacts.getAllFullyQualifiedNames()) { | ||
if (config.only.length && !config.only.some(m => fullName.match(m))) continue | ||
if (config.except.length && config.except.some(m => fullName.match(m))) continue | ||
|
||
const { abi, sourceName, contractName, bytecode, deployedBytecode } = await hre.artifacts.readArtifact(fullName) | ||
|
||
if (!abi.length) continue | ||
|
||
const destination = path.resolve( | ||
outputDirectory, | ||
config.flat ? '' : sourceName, | ||
contractName, | ||
) + '.json' | ||
|
||
if (!fs.existsSync(path.dirname(destination))) { | ||
fs.mkdirSync(path.dirname(destination), { recursive: true }) | ||
} | ||
|
||
fs.writeFileSync(destination, `${JSON.stringify({ abi, bytecode, deployedBytecode }, null, config.spacing)}\n`, { flag: 'w' }) | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.16; | ||
|
||
contract DummyContract { | ||
uint256 private value = 5; | ||
|
||
function getValue() public view returns (uint256) { | ||
return value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import '@typechain/hardhat' | ||
import '@nomiclabs/hardhat-waffle' | ||
import './abi-exporter' | ||
|
||
import compiler from './.compiler.json' | ||
|
||
module.exports = { | ||
paths: { | ||
sources: './contracts', | ||
artifacts: './build', | ||
cache: './cache', | ||
}, | ||
abiExporter: { | ||
path: './build', | ||
flat: true, | ||
spacing: 2, | ||
}, | ||
networks: { | ||
hardhat: { | ||
allowUnlimitedContractSize: true, | ||
}, | ||
}, | ||
typechain: { | ||
outDir: 'build/types', | ||
target: 'ethers-v5', | ||
}, | ||
solidity: { | ||
compilers: [compiler], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "@trusttoken-smart-contracts/contracts-por", | ||
"version": "0.0.1", | ||
"description": "Updates to TUSD contracts for Proof of Reserve feature", | ||
"private": true, | ||
"scripts": { | ||
"clean": "rm -rf ./build && hardhat clean", | ||
"build:hardhat": "hardhat compile", | ||
"build:typechain": "typechain --target ethers-v5 --out-dir build/types 'build/*.json'", | ||
"build": "yarn clean && yarn build:hardhat && yarn build:typechain && mars", | ||
"test": "mocha 'test/**/*.test.ts'" | ||
}, | ||
"dependencies": { | ||
"ethereum-mars": "0.2.5" | ||
}, | ||
"devDependencies": { | ||
"@ethersproject/abi": "^5.7.0", | ||
"@ethersproject/bytes": "^5.7.0", | ||
"@ethersproject/providers": "^5.7.0", | ||
"@nomiclabs/hardhat-waffle": "^2.0.3", | ||
"@typechain/ethers-v5": "^10.0.0", | ||
"@typechain/hardhat": "^6.0.0", | ||
"@types/chai": "^4.3.3", | ||
"@types/mocha": "^9.1.1", | ||
"@types/node": "^17.0.34", | ||
"chai": "^4.3.6", | ||
"ethereum-waffle": "4.0.7", | ||
"ethers": "^5.7.0", | ||
"hardhat": "~2.10.2", | ||
"mocha": "^10.0.0", | ||
"solc": "0.8.16", | ||
"ts-node": "^10.7.0", | ||
"tsconfig-paths": "^4.1.0", | ||
"typechain": "^8.0.0", | ||
"typescript": "4.5.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { expect, use } from 'chai' | ||
import { solidity } from 'ethereum-waffle' | ||
import { setupFixtureLoader } from './setup' | ||
import { dummyContractFixture } from 'fixtures/dummyContractFixture' | ||
|
||
use(solidity) | ||
|
||
describe('DummyContract', () => { | ||
const loadFixture = setupFixtureLoader() | ||
|
||
it('should have a constructor', async () => { | ||
const { dummyContract } = await loadFixture(dummyContractFixture) | ||
expect(await dummyContract.getValue()).to.eq(5) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { DummyContract__factory } from 'build/types' | ||
import { Wallet } from 'ethers' | ||
|
||
export async function dummyContractFixture([wallet]: Wallet[]) { | ||
const dummyContract = await new DummyContract__factory(wallet).deploy() | ||
return { dummyContract } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { Fixture, MockProvider } from 'ethereum-waffle' | ||
import { waffle } from 'hardhat' | ||
import { Wallet } from 'ethers' | ||
import './utils/hardhatPatches.ts' | ||
|
||
type FixtureLoader = ReturnType<typeof waffle.createFixtureLoader> | ||
interface FixtureReturns { | ||
provider: MockProvider, | ||
wallet: Wallet, | ||
other: Wallet, | ||
another: Wallet, | ||
} | ||
|
||
let loadFixture: ReturnType<typeof setupOnce> | undefined | ||
export function setupFixtureLoader() { | ||
if (!loadFixture) { | ||
loadFixture = setupOnce() | ||
} | ||
return loadFixture | ||
} | ||
|
||
type CurrentLoader = { loader: FixtureLoader, returns: FixtureReturns, fixture: Fixture<any> } | ||
|
||
function setupOnce() { | ||
let currentLoader: CurrentLoader = { | ||
loader: {} as FixtureLoader, | ||
returns: {} as FixtureReturns, | ||
fixture: {} as Fixture<any>, | ||
} | ||
|
||
async function makeLoader(): Promise<{ loader: FixtureLoader, returns: FixtureReturns }> { | ||
const { provider } = waffle | ||
await provider.send('hardhat_reset', []) | ||
const [wallet, other, another, ...rest] = provider.getWallets() | ||
const loader = waffle.createFixtureLoader([wallet, other, another, ...rest], provider) | ||
const returns = { provider, wallet, other, another } | ||
return { loader, returns } | ||
} | ||
|
||
async function loadFixture<T>(fixture: Fixture<T>): Promise<T & FixtureReturns> { | ||
// This function creates a new provider for each fixture, because of bugs | ||
// in ganache that clear contract code on evm_revert | ||
const { loader, returns } = currentLoader.fixture === fixture ? currentLoader : await makeLoader() | ||
currentLoader = { fixture, loader, returns } | ||
const result = await loader(fixture) | ||
return { ...returns, ...result } | ||
} | ||
|
||
return loadFixture | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { waffle } from 'hardhat' | ||
import type { RecordedCall } from 'ethereum-waffle' | ||
import { utils } from 'ethers' | ||
|
||
const init = (waffle.provider as any)._hardhatNetwork.provider._wrapped._wrapped._wrapped._init | ||
|
||
function patchSkipGasCostCheck() { | ||
const originalProcess = (waffle.provider as any)._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule.processRequest.bind( | ||
(waffle.provider as any)._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule, | ||
) | ||
;(waffle.provider as any)._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule.processRequest = ( | ||
method: string, | ||
params: any[], | ||
) => { | ||
if (method === 'eth_estimateGas') { | ||
return '0xB71B00' | ||
} else { | ||
return originalProcess(method, params) | ||
} | ||
} | ||
} | ||
|
||
class CallHistory { | ||
recordedCalls: RecordedCall[] = []; | ||
|
||
addUniqueCall(call: RecordedCall) { | ||
if (!this.recordedCalls.find(c => c.address === call.address && c.data === call.data)) { | ||
this.recordedCalls.push(call) | ||
} | ||
} | ||
|
||
clearAll() { | ||
this.recordedCalls = [] | ||
} | ||
} | ||
|
||
function toRecordedCall(message: any): RecordedCall { | ||
return { | ||
address: message.to?.buf ? utils.getAddress(utils.hexlify(message.to.buf)) : undefined, | ||
data: message.data ? utils.hexlify(message.data) : '0x', | ||
} | ||
} | ||
|
||
const callHistory = new CallHistory(); | ||
(waffle.provider as any).clearCallHistory = () => { | ||
callHistory.clearAll() | ||
} | ||
|
||
let beforeMessageListener: (message: any) => void | undefined; | ||
|
||
(waffle.provider as any)._hardhatNetwork.provider._wrapped._wrapped._wrapped._init = async function () { | ||
await init.apply(this) | ||
if (typeof beforeMessageListener === 'function') { | ||
// hast to be here because of weird behaviour of init function | ||
(waffle.provider as any) | ||
._hardhatNetwork | ||
.provider | ||
._wrapped | ||
._wrapped | ||
._wrapped | ||
._node | ||
._vmTracer | ||
._vm | ||
.off('beforeMessage', beforeMessageListener) | ||
} | ||
if ((waffle.provider as any)._hardhatNetwork.provider._wrapped._wrapped._wrapped._node._vmTracer._vm.listenerCount('beforeMessage') < 2) { | ||
patchSkipGasCostCheck() | ||
} | ||
beforeMessageListener = (message: any) => { | ||
callHistory.addUniqueCall(toRecordedCall(message)) | ||
} | ||
const provider: any = waffle.provider | ||
provider.callHistory = callHistory.recordedCalls; | ||
(waffle.provider as any) | ||
._hardhatNetwork.provider | ||
._wrapped._wrapped | ||
._wrapped | ||
._node | ||
._vmTracer | ||
._vm | ||
.on('beforeMessage', beforeMessageListener) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"compilerOptions": { | ||
"resolveJsonModule": true, | ||
"esModuleInterop": true, | ||
"moduleResolution": "node", | ||
"skipLibCheck": true, | ||
"target": "esnext", | ||
"sourceMap": true, | ||
"baseUrl": ".", | ||
"paths": { | ||
"build/*": ["build/*"], | ||
"build": ["build"], | ||
"fixtures/*": ["test/fixtures/*"], | ||
"fixtures": ["test/fixtures"], | ||
"contracts/*": ["build/types/*"], | ||
"contracts": ["build/types", "build/types/factories"], | ||
"utils/*": ["test/utils/*"], | ||
"utils": ["test/utils"], | ||
"config/*": ["test/config/*"], | ||
"config": ["test/config"], | ||
} | ||
}, | ||
"include": [ | ||
"build", | ||
"contracts", | ||
"test", | ||
"scripts", | ||
] | ||
} |
Oops, something went wrong.