From 84f05abe4d106a16a2b7ea2d4f7ac2c6e11bdddb Mon Sep 17 00:00:00 2001 From: PatrickAlphaC Date: Wed, 16 Dec 2020 12:24:43 -0500 Subject: [PATCH] wip --- contracts/RandomNumberConsumer.sol | 6 +- migrations/3_price_consumer_v3.js | 2 +- migrations/4_random_number_consumer.js | 20 ++ .../fund-contract.js | 24 ++ test/MyContract_test.js | 4 +- test/PriceConsumerV3_test.js | 259 ++---------------- truffle-config.js | 12 + 7 files changed, 94 insertions(+), 233 deletions(-) create mode 100644 migrations/4_random_number_consumer.js create mode 100644 scripts/random-number-consumer-scripts/fund-contract.js diff --git a/contracts/RandomNumberConsumer.sol b/contracts/RandomNumberConsumer.sol index 189071d..84cacdc 100644 --- a/contracts/RandomNumberConsumer.sol +++ b/contracts/RandomNumberConsumer.sol @@ -7,6 +7,7 @@ contract RandomNumberConsumer is VRFConsumerBase { bytes32 internal keyHash; uint256 internal fee; + address public linkTokenAddress; uint256 public randomResult; @@ -18,12 +19,13 @@ contract RandomNumberConsumer is VRFConsumerBase { * LINK token address: 0xa36085F69e2889c224210F603D836748e7dC0088 * Key Hash: 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4 */ - constructor() + constructor(address _linkTokenAddress) VRFConsumerBase( 0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9, // VRF Coordinator - 0xa36085F69e2889c224210F603D836748e7dC0088 // LINK Token + _linkTokenAddress // LINK Token ) public { + linkTokenAddress = _linkTokenAddress keyHash = 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4; fee = 0.1 * 10 ** 18; // 0.1 LINK } diff --git a/migrations/3_price_consumer_v3.js b/migrations/3_price_consumer_v3.js index e06f3be..cc62c9a 100644 --- a/migrations/3_price_consumer_v3.js +++ b/migrations/3_price_consumer_v3.js @@ -5,7 +5,7 @@ module.exports = async (deployer, network, [defaultAccount]) => { // token and the Oracle contract if (!network.startsWith('live')) { try { - await deployer.deploy(MyContract, { from: defaultAccount }) + await deployer.deploy(PriceConsumerV3, { from: defaultAccount }) } catch (err) { console.error(err) } diff --git a/migrations/4_random_number_consumer.js b/migrations/4_random_number_consumer.js new file mode 100644 index 0000000..846687f --- /dev/null +++ b/migrations/4_random_number_consumer.js @@ -0,0 +1,20 @@ +const RandomNumberConsumer = artifacts.require('RandomNumberConsumer') +const { LinkToken } = require('@chainlink/contracts/truffle/v0.4/LinkToken') + +module.exports = async (deployer, network, [defaultAccount]) => { + // Local (development) networks need their own deployment of the LINK + // token and the Oracle contract + if (!network.startsWith('live')) { + LinkToken.setProvider(deployer.provider) + try { + await deployer.deploy(LinkToken, { from: defaultAccount }) + await deployer.deploy(RandomNumberConsumer, LinkToken.address) + } catch (err) { + console.error(err) + } + } else { + // For live networks, use the 0 address to allow the ChainlinkRegistry + // contract automatically retrieve the correct address for you + deployer.deploy(MyContract, '0x0000000000000000000000000000000000000000') + } +} diff --git a/scripts/random-number-consumer-scripts/fund-contract.js b/scripts/random-number-consumer-scripts/fund-contract.js new file mode 100644 index 0000000..c244a3a --- /dev/null +++ b/scripts/random-number-consumer-scripts/fund-contract.js @@ -0,0 +1,24 @@ +const RandomNumberConsumer = artifacts.require('RandomNumberConsumer') +const LinkTokenInterface = artifacts.require('LinkTokenInterface') + +/* + This script is meant to assist with funding the requesting + contract with LINK. It will send 1 LINK to the requesting + contract for ease-of-use. Any extra LINK present on the contract + can be retrieved by calling the withdrawLink() function. +*/ + +const payment = process.env.TRUFFLE_CL_BOX_PAYMENT || '1000000000000000000' + +module.exports = async callback => { + try { + const randomNumberConsumer = await RandomNumberConsumer.deployed() + const tokenAddress = await randomNumberConsumer.getChainlinkToken() + const token = await LinkTokenInterface.at(tokenAddress) + console.log('Funding contract:', randomNumberConsumer.address) + const tx = await token.transfer(randomNumberConsumer.address, payment) + callback(tx.tx) + } catch (err) { + callback(err) + } +} diff --git a/test/MyContract_test.js b/test/MyContract_test.js index ac0c8a5..0222eaf 100644 --- a/test/MyContract_test.js +++ b/test/MyContract_test.js @@ -5,7 +5,7 @@ const { expectRevert, time } = require('@openzeppelin/test-helpers') contract('MyContract', accounts => { const { LinkToken } = require('@chainlink/contracts/truffle/v0.4/LinkToken') const { Oracle } = require('@chainlink/contracts/truffle/v0.6/Oracle') - const MyContract = artifacts.require('MyContract.sol') + const MyContract = artifacts.require('MyContract') const defaultAccount = accounts[0] const oracleNode = accounts[1] @@ -17,6 +17,8 @@ contract('MyContract', accounts => { // the type of data, but will not work on a public testnet. // For the latest JobIDs, visit our docs here: // https://docs.chain.link/docs/testnet-oracles + // Alternativly, visti a node listing service and choose your + // own nodes: https://market.link/ const jobId = web3.utils.toHex('4c7b7ffb66b344fbaa64995af81e355a') const url = 'https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD,EUR,JPY' diff --git a/test/PriceConsumerV3_test.js b/test/PriceConsumerV3_test.js index 7c9681b..886d02c 100644 --- a/test/PriceConsumerV3_test.js +++ b/test/PriceConsumerV3_test.js @@ -1,229 +1,30 @@ -// /* eslint-disable @typescript-eslint/no-var-requires */ -// // const { expectRevert, time } = require('@openzeppelin/test-helpers') - -// contract('PriceFeedConsumerV3', accounts => { -// const PriceFeedConsumerV3 = artifacts.require('PriceFeedConsumerV3.sol') - -// const defaultAccount = accounts[0] -// // These parameters are used to validate the data was received -// // on the deployed oracle contract. The Job ID only represents -// // the type of data, but will not work on a public testnet. -// // For the latest JobIDs, visit our docs here: -// // https://docs.chain.link/docs/testnet-oracles -// const jobId = web3.utils.toHex('4c7b7ffb66b344fbaa64995af81e355a') -// const url = -// 'https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD,EUR,JPY' -// const path = 'USD' -// const times = 100 - -// // Represents 1 LINK for testnet requests -// const payment = web3.utils.toWei('1') - -// let link, oc, cc - -// beforeEach(async () => { -// link = await LinkToken.new({ from: defaultAccount }) -// oc = await Oracle.new(link.address, { from: defaultAccount }) -// cc = await MyContract.new(link.address, { from: consumer }) -// await oc.setFulfillmentPermission(oracleNode, true, { -// from: defaultAccount, -// }) -// }) - -// describe('#createRequest', () => { -// context('without LINK', () => { -// it('reverts', async () => { -// await expectRevert.unspecified( -// cc.createRequestTo(oc.address, jobId, payment, url, path, times, { -// from: consumer, -// }), -// ) -// }) -// }) - -// context('with LINK', () => { -// let request - -// beforeEach(async () => { -// await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), { -// from: defaultAccount, -// }) -// }) - -// context('sending a request to a specific oracle contract address', () => { -// it('triggers a log event in the new Oracle contract', async () => { -// const tx = await cc.createRequestTo( -// oc.address, -// jobId, -// payment, -// url, -// path, -// times, -// { from: consumer }, -// ) -// request = oracle.decodeRunRequest(tx.receipt.rawLogs[3]) -// assert.equal(oc.address, tx.receipt.rawLogs[3].address) -// assert.equal( -// request.topic, -// web3.utils.keccak256( -// 'OracleRequest(bytes32,address,bytes32,uint256,address,bytes4,uint256,uint256,bytes)', -// ), -// ) -// }) -// }) -// }) -// }) - -// describe('#fulfill', () => { -// const expected = 50000 -// const response = web3.utils.padLeft(web3.utils.toHex(expected), 64) -// let request - -// beforeEach(async () => { -// await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), { -// from: defaultAccount, -// }) -// const tx = await cc.createRequestTo( -// oc.address, -// jobId, -// payment, -// url, -// path, -// times, -// { from: consumer }, -// ) -// request = oracle.decodeRunRequest(tx.receipt.rawLogs[3]) -// await oc.fulfillOracleRequest( -// ...oracle.convertFufillParams(request, response, { -// from: oracleNode, -// gas: 500000, -// }), -// ) -// }) - -// it('records the data given to it by the oracle', async () => { -// const currentPrice = await cc.data.call() -// assert.equal( -// web3.utils.padLeft(web3.utils.toHex(currentPrice), 64), -// web3.utils.padLeft(expected, 64), -// ) -// }) - -// context('when my contract does not recognize the request ID', () => { -// const otherId = web3.utils.toHex('otherId') - -// beforeEach(async () => { -// request.id = otherId -// }) - -// it('does not accept the data provided', async () => { -// await expectRevert.unspecified( -// oc.fulfillOracleRequest( -// ...oracle.convertFufillParams(request, response, { -// from: oracleNode, -// }), -// ), -// ) -// }) -// }) - -// context('when called by anyone other than the oracle contract', () => { -// it('does not accept the data provided', async () => { -// await expectRevert.unspecified( -// cc.fulfill(request.requestId, response, { from: stranger }), -// ) -// }) -// }) -// }) - -// describe('#cancelRequest', () => { -// let request - -// beforeEach(async () => { -// await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), { -// from: defaultAccount, -// }) -// const tx = await cc.createRequestTo( -// oc.address, -// jobId, -// payment, -// url, -// path, -// times, -// { from: consumer }, -// ) -// request = oracle.decodeRunRequest(tx.receipt.rawLogs[3]) -// }) - -// context('before the expiration time', () => { -// it('cannot cancel a request', async () => { -// await expectRevert( -// cc.cancelRequest( -// request.requestId, -// request.payment, -// request.callbackFunc, -// request.expiration, -// { from: consumer }, -// ), -// 'Request is not expired', -// ) -// }) -// }) - -// context('after the expiration time', () => { -// beforeEach(async () => { -// await time.increase(300) -// }) - -// context('when called by a non-owner', () => { -// it('cannot cancel a request', async () => { -// await expectRevert.unspecified( -// cc.cancelRequest( -// request.requestId, -// request.payment, -// request.callbackFunc, -// request.expiration, -// { from: stranger }, -// ), -// ) -// }) -// }) - -// context('when called by an owner', () => { -// it('can cancel a request', async () => { -// await cc.cancelRequest( -// request.requestId, -// request.payment, -// request.callbackFunc, -// request.expiration, -// { from: consumer }, -// ) -// }) -// }) -// }) -// }) - -// describe('#withdrawLink', () => { -// beforeEach(async () => { -// await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), { -// from: defaultAccount, -// }) -// }) - -// context('when called by a non-owner', () => { -// it('cannot withdraw', async () => { -// await expectRevert.unspecified(cc.withdrawLink({ from: stranger })) -// }) -// }) - -// context('when called by the owner', () => { -// it('transfers LINK to the owner', async () => { -// const beforeBalance = await link.balanceOf(consumer) -// assert.equal(beforeBalance, '0') -// await cc.withdrawLink({ from: consumer }) -// const afterBalance = await link.balanceOf(consumer) -// assert.equal(afterBalance, web3.utils.toWei('1', 'ether')) -// }) -// }) -// }) -// }) +/* eslint-disable @typescript-eslint/no-var-requires + +This repo is for testing on a live network only. +You can get truffle teams and do a forking version of +these tests. + +*/ + +contract('PriceConsumerV3', accounts => { + const PriceConsumerV3 = artifacts.require('PriceConsumerV3') + + const defaultAccount = accounts[0] + // The addresses here can be found in the chainlink docs + // https://docs.chain.link/docs/ethereum-addresses + + let priceConsumerV3 + + describe('#getLatestPrice', () => { + it('returns a price', async () => { + // priceConsumerV3 = await PriceConsumerV3.new() + // const price = await priceConsumerV3.getLatestPrice() + // assert.equal(price > 0, true) + // assert.equal( + // web3.utils.padLeft(web3.utils.toHex(price), 64), + // web3.utils.padLeft(expected, 64), + // ) + assert(true, true) + }) + }) +}) diff --git a/truffle-config.js b/truffle-config.js index e267a41..6088038 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -21,6 +21,18 @@ module.exports = { // Necessary due to https://github.com/trufflesuite/truffle/issues/3008 skipDryRun: true, } + // if you want to test the price feeds, uncomment and run a local forked + // ganache server + // , + // test: { + // provider: () => { + // return new HDWalletProvider(process.env.MNEMONIC, process.env.RPC_URL) + // }, + // network_id: '*', + // // ~~Necessary due to https://github.com/trufflesuite/truffle/issues/1971~~ + // // Necessary due to https://github.com/trufflesuite/truffle/issues/3008 + // skipDryRun: true, + // } }, compilers: { solc: {