From a2b4823fcfce0c84dabe5f7ef4ffe2b730b28cdd Mon Sep 17 00:00:00 2001 From: emochka2007 Date: Sat, 18 May 2024 02:01:27 +0300 Subject: [PATCH] salaries ready, started data feed chainlink --- README.md | 3 +- chain-api/hardhat.config.ts | 6 +- chain-api/package-lock.json | 8 +- .../contract-interact/dto/multi-sig.dto.ts | 4 + .../src/contract-interact/ethers.helpers.ts | 3 +- chain-api/src/hardhat/contracts/License.sol | 101 ++++++++++++++++++ chain-api/src/hardhat/contracts/Lock.sol | 34 ------ .../src/hardhat/contracts/MultiSigWallet.sol | 29 ----- .../src/hardhat/contracts/PriceFeedMock.sol | 18 ++++ chain-api/src/hardhat/contracts/Salaries.sol | 14 ++- .../multi-sig-interact.controller.ts | 13 ++- .../modules/multi-sig/multi-sig.service.ts | 19 ++-- .../salaries/salaries-interact.controller.ts | 20 +++- .../hardhat/modules/salaries/salaries.dto.ts | 5 + .../modules/salaries/salaries.service.ts | 5 +- chain-api/src/hardhat/test/Salaries.test.ts | 69 ++++++++++++ chain-api/src/provider/provider.service.ts | 4 +- 17 files changed, 254 insertions(+), 101 deletions(-) create mode 100644 chain-api/src/hardhat/contracts/License.sol delete mode 100644 chain-api/src/hardhat/contracts/Lock.sol create mode 100644 chain-api/src/hardhat/contracts/PriceFeedMock.sol create mode 100644 chain-api/src/hardhat/test/Salaries.test.ts diff --git a/README.md b/README.md index f75e37c..e9dddbb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ ![LOGIN FLOW](./login-flow.png "Login") -![Example architecture](./arch.png "Arch") + +[//]: # (![Example architecture](./arch.png "Arch")) ![License](./license.png "Arch") ![Salaries](./salaries.png "Arch") diff --git a/chain-api/hardhat.config.ts b/chain-api/hardhat.config.ts index 21a1c97..34b23d7 100644 --- a/chain-api/hardhat.config.ts +++ b/chain-api/hardhat.config.ts @@ -11,9 +11,13 @@ const config = { accounts: [process.env.POLYGON_PK || ''], }, }, + typechain: { + outDir: 'typechain', + target: 'ethers-v6', + }, paths: { sources: './src/hardhat/contracts', - // tests: './src/hardhat/test', + tests: './src/hardhat/test', ignition: './src/hardhat/ignition', cache: './src/hardhat/cache', artifacts: './src/hardhat/artifacts', diff --git a/chain-api/package-lock.json b/chain-api/package-lock.json index 6c62f3e..c39aca9 100644 --- a/chain-api/package-lock.json +++ b/chain-api/package-lock.json @@ -6600,15 +6600,15 @@ } }, "node_modules/chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", "peer": true, "dependencies": { "check-error": "^1.0.2" }, "peerDependencies": { - "chai": ">= 2.1.2 < 5" + "chai": ">= 2.1.2 < 6" } }, "node_modules/chalk": { diff --git a/chain-api/src/contract-interact/dto/multi-sig.dto.ts b/chain-api/src/contract-interact/dto/multi-sig.dto.ts index 6ef37e0..2803201 100644 --- a/chain-api/src/contract-interact/dto/multi-sig.dto.ts +++ b/chain-api/src/contract-interact/dto/multi-sig.dto.ts @@ -42,3 +42,7 @@ export class DepositContractDto { @ApiProperty() value: string; } +export class DeployMultiSigResponseDto { + @IsString() + address: string; +} diff --git a/chain-api/src/contract-interact/ethers.helpers.ts b/chain-api/src/contract-interact/ethers.helpers.ts index f77b017..d3b5148 100644 --- a/chain-api/src/contract-interact/ethers.helpers.ts +++ b/chain-api/src/contract-interact/ethers.helpers.ts @@ -3,8 +3,9 @@ import { TransactionReceipt, ethers } from 'ethers'; export const parseLogs = ( txReceipt: TransactionReceipt, contract: ethers.Contract, + eventName: string, ) => { return txReceipt.logs .map((log) => contract.interface.parseLog(log)) - .find((log) => !!log); + .find((log) => !!log && log.fragment.name === eventName); }; diff --git a/chain-api/src/hardhat/contracts/License.sol b/chain-api/src/hardhat/contracts/License.sol new file mode 100644 index 0000000..fa79f80 --- /dev/null +++ b/chain-api/src/hardhat/contracts/License.sol @@ -0,0 +1,101 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol"; +import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol"; + +/** + * Request testnet LINK and ETH here: https://faucets.chain.link/ + * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/ + */ + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + */ +contract LinkWellStringBytesConsumerContractExample is ChainlinkClient, ConfirmedOwner { + using Chainlink for Chainlink.Request; + + address private oracleAddress; + bytes32 private jobId; + uint256 private fee; + + constructor() ConfirmedOwner(msg.sender) { + _setChainlinkToken(0x0Fd9e8d3aF1aaee056EB9e802c3A762a667b1904); + setOracleAddress(0xd36c6B1777c7f3Db1B3201bDD87081A9045B7b46); + setJobId("8ced832954544a3c98543c94a51d6a8d"); + setFeeInHundredthsOfLink(0); // 0 LINK + } + + // Send a request to the Chainlink oracle + function request() public { + + Chainlink.Request memory req = _buildOperatorRequest(jobId, this.fulfill.selector); + + // DEFINE THE REQUEST PARAMETERS (example) + req._add('method', 'POST'); + req._add('url', 'https://httpbin.org/post'); + req._add('headers', '["accept", "application/json", "set-cookie", "sid=14A52"]'); + req._add('body', '{"data":[{"id":1,"name":"Bitcoin","price":20194.52},{"id":2,"name":"Ethereum","price":1850.46},{"id":3,"name":"Chainlink","price":18.36}]}'); + req._add('contact', ''); // PLEASE ENTER YOUR CONTACT INFO. this allows us to notify you in the event of any emergencies related to your request (ie, bugs, downtime, etc.). example values: 'derek_linkwellnodes.io' (Discord handle) OR 'derek@linkwellnodes.io' OR '+1-617-545-4721' + + // The following curl command simulates the above request parameters: + // curl 'https://httpbin.org/post' --request 'POST' --header 'content-type: application/json' --header 'set-cookie: sid=14A52' --data '{"data":[{"id":1,"name":"Bitcoin","price":20194.52},{"id":2,"name":"Ethereum","price":1850.46},{"id":3,"name":"Chainlink","price":18.36}]}' + + // PROCESS THE RESULT (example) + req._add('path', 'json,data,0,name'); + + // Send the request to the Chainlink oracle + _sendOperatorRequest(req, fee); + } + + bytes public responseBytes; + + // Receive the result from the Chainlink oracle + event RequestFulfilled(bytes32 indexed requestId); + function fulfill(bytes32 requestId, bytes memory bytesData) public recordChainlinkFulfillment(requestId) { + // Process the oracle response + // emit RequestFulfilled(requestId); // (optional) emits this event in the on-chain transaction logs, allowing Web3 applications to listen for this transaction + responseBytes = bytesData; // example value: 0x426974636f696e + } + + // Retrieve the response data as a string + function getResponseString() public view onlyOwner returns (string memory) { + return string(responseBytes); // example value: Bitcoin + } + + // Update oracle address + function setOracleAddress(address _oracleAddress) public onlyOwner { + oracleAddress = _oracleAddress; + _setChainlinkOracle(_oracleAddress); + } + function getOracleAddress() public view onlyOwner returns (address) { + return oracleAddress; + } + + // Update jobId + function setJobId(string memory _jobId) public onlyOwner { + jobId = bytes32(bytes(_jobId)); + } + function getJobId() public view onlyOwner returns (string memory) { + return string(abi.encodePacked(jobId)); + } + + // Update fees + function setFeeInJuels(uint256 _feeInJuels) public onlyOwner { + fee = _feeInJuels; + } + function setFeeInHundredthsOfLink(uint256 _feeInHundredthsOfLink) public onlyOwner { + setFeeInJuels((_feeInHundredthsOfLink * LINK_DIVISIBILITY) / 100); + } + function getFeeInHundredthsOfLink() public view onlyOwner returns (uint256) { + return (fee * 100) / LINK_DIVISIBILITY; + } + + function withdrawLink() public onlyOwner { + LinkTokenInterface link = LinkTokenInterface(_chainlinkTokenAddress()); + require( + link.transfer(msg.sender, link.balanceOf(address(this))), + "Unable to transfer" + ); + } +} \ No newline at end of file diff --git a/chain-api/src/hardhat/contracts/Lock.sol b/chain-api/src/hardhat/contracts/Lock.sol deleted file mode 100644 index 1efbef3..0000000 --- a/chain-api/src/hardhat/contracts/Lock.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.24; - -// Uncomment this line to use console.log -// import "hardhat/console.sol"; - -contract Lock { - uint public unlockTime; - address payable public owner; - - event Withdrawal(uint amount, uint when); - - constructor(uint _unlockTime) payable { - require( - block.timestamp < _unlockTime, - "Unlock time should be in the future" - ); - - unlockTime = _unlockTime; - owner = payable(msg.sender); - } - - function withdraw() public { - // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal - // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp); - - require(block.timestamp >= unlockTime, "You can't withdraw yet"); - require(msg.sender == owner, "You aren't the owner"); - - emit Withdrawal(address(this).balance, block.timestamp); - - owner.transfer(address(this).balance); - } -} diff --git a/chain-api/src/hardhat/contracts/MultiSigWallet.sol b/chain-api/src/hardhat/contracts/MultiSigWallet.sol index 0ffba22..83dd3b2 100644 --- a/chain-api/src/hardhat/contracts/MultiSigWallet.sol +++ b/chain-api/src/hardhat/contracts/MultiSigWallet.sol @@ -20,8 +20,6 @@ contract MultiSigWallet { event RevokeConfirmation(address indexed owner, uint indexed txIndex); event ExecuteTransaction(address indexed owner, uint indexed txIndex); event ExecuteTransactionFailed(address indexed owner, uint indexed txIndex, string reason); - event Payout(address indexed employee, uint salaryInETH); - event PayoutFailed(address indexed employee, uint salaryInETH, string reason); address[] public owners; @@ -132,9 +130,6 @@ contract MultiSigWallet { if (success) { transaction.executed = true; emit ExecuteTransaction(msg.sender, _txIndex); - if (returnData.length > 0) { - emitEventFromReturnData(returnData); - } } else { // Get the revert reason and emit it if (returnData.length > 0) { @@ -150,30 +145,6 @@ contract MultiSigWallet { } } - function emitEventFromReturnData(bytes memory returnData) internal { - // Decode the selector from returnData - bytes4 selector; - assembly { - selector := mload(add(returnData, 32)) - } - - // Match the selector to the known events - if (selector == Payout.selector) { - (address employee, uint salaryInETH) = abi.decode(slice(returnData, 4, returnData.length), (address, uint)); - emit Payout(employee, salaryInETH); - } else if (selector == PayoutFailed.selector) { - (address employee, uint salaryInETH, string memory reason) = abi.decode(slice(returnData, 4, returnData.length), (address, uint, string)); - emit PayoutFailed(employee, salaryInETH, reason); - } - } - function slice(bytes memory data, uint start, uint length) internal pure returns (bytes memory) { - bytes memory result = new bytes(length); - for (uint i = 0; i < length; i++) { - result[i] = data[start + i]; - } - return result; - } - function revokeConfirmation( uint _txIndex ) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) { diff --git a/chain-api/src/hardhat/contracts/PriceFeedMock.sol b/chain-api/src/hardhat/contracts/PriceFeedMock.sol new file mode 100644 index 0000000..5d2dce9 --- /dev/null +++ b/chain-api/src/hardhat/contracts/PriceFeedMock.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +contract PriceFeedMock { + function latestRoundData() + external + pure + returns ( + uint80 roundId, + int answer, + uint startedAt, + uint updatedAt, + uint80 answeredInRound + ) + { + return (0, 3087, 0, 0, 0); // Mock data, 1 ETH = 3087 USDT + } +} diff --git a/chain-api/src/hardhat/contracts/Salaries.sol b/chain-api/src/hardhat/contracts/Salaries.sol index 0c2d3ed..1f6a132 100644 --- a/chain-api/src/hardhat/contracts/Salaries.sol +++ b/chain-api/src/hardhat/contracts/Salaries.sol @@ -21,7 +21,7 @@ contract Salaries { _; } - function getSalary(address employee) public view returns(uint) { + function getUsdtSalary(address employee) public view returns(uint) { return salaries[employee]; } @@ -43,16 +43,18 @@ contract Salaries { salaries[employee] = salaryInUSDT; } - function payoutInETH(address payable employee) external onlyMultisig { + function getEmployeeSalaryInEth(address employee) public view returns(uint){ uint salaryInUSDT = salaries[employee]; require(salaryInUSDT > 0, 'No salary set'); int ethToUSDT = getLatestUSDTPriceInETH(); require(ethToUSDT > 0, 'Invalid price data'); - - // Convert salary from USDT to ETH based on the latest price uint salaryInETH = uint(salaryInUSDT * 1e18) / uint(ethToUSDT); + return salaryInETH * 1e8; + } + function payoutInETH(address payable employee) external onlyMultisig { + uint salaryInETH = getEmployeeSalaryInEth(employee); // Check sufficient balance require( address(this).balance >= salaryInETH, @@ -67,10 +69,6 @@ contract Salaries { } } - function dummy() public pure returns (uint){ - return 1337; - } - // Fallback to receive ETH receive() external payable {} } diff --git a/chain-api/src/hardhat/modules/multi-sig/multi-sig-interact.controller.ts b/chain-api/src/hardhat/modules/multi-sig/multi-sig-interact.controller.ts index b4722ab..07d0d49 100644 --- a/chain-api/src/hardhat/modules/multi-sig/multi-sig-interact.controller.ts +++ b/chain-api/src/hardhat/modules/multi-sig/multi-sig-interact.controller.ts @@ -3,6 +3,7 @@ import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; import { MultiSigWalletService } from 'src/hardhat/modules/multi-sig/multi-sig.service'; import { ConfirmTransactionDto, + DeployMultiSigResponseDto, DepositContractDto, ExecuteTransactionDto, GetTransactionDto, @@ -15,9 +16,17 @@ import { MultiSigWalletDto } from './multi-sig.dto'; export class MultiSigInteractController { constructor(private readonly multiSigWalletService: MultiSigWalletService) {} + @ApiOkResponse({ + type: DeployMultiSigResponseDto, + }) @Post('deploy') - async deploy(@Body() dto: MultiSigWalletDto) { - return this.multiSigWalletService.deploy(dto); + async deploy( + @Body() dto: MultiSigWalletDto, + ): Promise { + const addr = await this.multiSigWalletService.deploy(dto); + return { + address: addr, + }; } @Get('owners/:address') async getOwners(@Param('address') address: string) { diff --git a/chain-api/src/hardhat/modules/multi-sig/multi-sig.service.ts b/chain-api/src/hardhat/modules/multi-sig/multi-sig.service.ts index cc54946..f913f65 100644 --- a/chain-api/src/hardhat/modules/multi-sig/multi-sig.service.ts +++ b/chain-api/src/hardhat/modules/multi-sig/multi-sig.service.ts @@ -1,5 +1,4 @@ -import { TransactionReceipt, ethers, parseEther } from 'ethers'; -import { ConfigService } from '@nestjs/config'; +import { ethers, parseEther, TransactionReceipt } from 'ethers'; import * as hre from 'hardhat'; import { BaseContractService } from '../base-contract.service'; import { MultiSigWalletDto } from './multi-sig.dto'; @@ -27,8 +26,7 @@ export class MultiSigWalletService extends BaseContractService { dto.confirmations, ); await myContract.waitForDeployment(); - const address = myContract.getAddress(); - return address; + return myContract.getAddress(); } async getOwners(address: string) { @@ -39,9 +37,7 @@ export class MultiSigWalletService extends BaseContractService { const contract = new ethers.Contract(address, abi, signer); - const owners = await contract.getOwners(); - - return owners; + return await contract.getOwners(); } async submitTransaction(dto: SubmitTransactionDto) { @@ -54,7 +50,7 @@ export class MultiSigWalletService extends BaseContractService { const tx = await contract.submitTransaction(destination, value, data); const txResponse: TransactionReceipt = await tx.wait(); - const eventParse = parseLogs(txResponse, contract); + const eventParse = parseLogs(txResponse, contract, 'SubmitTransaction'); return { txHash: txResponse.hash, @@ -77,7 +73,7 @@ export class MultiSigWalletService extends BaseContractService { const txResponse: TransactionReceipt = await tx.wait(); - const eventParse = parseLogs(txResponse, contract); + const eventParse = parseLogs(txResponse, contract, 'ConfirmTransaction'); return { txHash: txResponse.hash, @@ -96,8 +92,7 @@ export class MultiSigWalletService extends BaseContractService { const tx = await contract.executeTransaction(index); const txResponse: TransactionReceipt = await tx.wait(); - console.log('=>(multi-sig.service.ts:99) txResponse', txResponse.logs); - const eventParse = parseLogs(txResponse, contract); + const eventParse = parseLogs(txResponse, contract, 'ExecuteTransaction'); return { txHash: txResponse.hash, sender: eventParse.args[0].toString(), @@ -155,7 +150,7 @@ export class MultiSigWalletService extends BaseContractService { const txResponse: TransactionReceipt = await tx.wait(); - const eventParse = parseLogs(txResponse, contract); + const eventParse = parseLogs(txResponse, contract, 'ExecuteTransaction'); return { txHash: txResponse.hash, diff --git a/chain-api/src/hardhat/modules/salaries/salaries-interact.controller.ts b/chain-api/src/hardhat/modules/salaries/salaries-interact.controller.ts index 0646fc5..fae89ef 100644 --- a/chain-api/src/hardhat/modules/salaries/salaries-interact.controller.ts +++ b/chain-api/src/hardhat/modules/salaries/salaries-interact.controller.ts @@ -2,20 +2,32 @@ import { Body, Controller, Get, Param, Post } from '@nestjs/common'; import { SalariesService } from './salaries.service'; import { CreatePayoutDto, + DeployContractResponseDto, GetEmployeeSalariesDto, SalariesDeployDto, SetSalaryDto, } from './salaries.dto'; -import { ApiTags } from '@nestjs/swagger'; -import { DepositContractDto } from '../../../contract-interact/dto/multi-sig.dto'; +import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; +import { + DeployMultiSigResponseDto, + DepositContractDto, +} from '../../../contract-interact/dto/multi-sig.dto'; @ApiTags('salaries') @Controller('salaries') export class SalariesController { constructor(private readonly salariesService: SalariesService) {} + @ApiOkResponse({ + type: DeployContractResponseDto, + }) @Post('deploy') - async deploy(@Body() dto: SalariesDeployDto) { - return this.salariesService.deploy(dto); + async deploy( + @Body() dto: SalariesDeployDto, + ): Promise { + const address = await this.salariesService.deploy(dto); + return { + address, + }; } @Get('usdt-price/:contractAddress') diff --git a/chain-api/src/hardhat/modules/salaries/salaries.dto.ts b/chain-api/src/hardhat/modules/salaries/salaries.dto.ts index 322ae38..5cee16d 100644 --- a/chain-api/src/hardhat/modules/salaries/salaries.dto.ts +++ b/chain-api/src/hardhat/modules/salaries/salaries.dto.ts @@ -35,3 +35,8 @@ export class CreatePayoutDto extends GeneralEmpoyeeSalaryDto { @IsString() multiSigWallet: string; } + +export class DeployContractResponseDto { + @IsString() + address: string; +} diff --git a/chain-api/src/hardhat/modules/salaries/salaries.service.ts b/chain-api/src/hardhat/modules/salaries/salaries.service.ts index 8bef96e..04ce55d 100644 --- a/chain-api/src/hardhat/modules/salaries/salaries.service.ts +++ b/chain-api/src/hardhat/modules/salaries/salaries.service.ts @@ -20,7 +20,7 @@ export class SalariesService extends BaseContractService { ) { super(providerService); } - async deploy(dto: SalariesDeployDto): Promise { + async deploy(dto: SalariesDeployDto) { const { abi, bytecode } = await hre.artifacts.readArtifact('Salaries'); const signer = await this.providerService.getSigner(); @@ -71,7 +71,7 @@ export class SalariesService extends BaseContractService { const contract = new ethers.Contract(contractAddress, abi, signer); - const answer: BigInt = await contract.getSalary(employeeAddress); + const answer: BigInt = await contract.getUsdtSalary(employeeAddress); return { salaryInUsd: answer.toString(), }; @@ -79,7 +79,6 @@ export class SalariesService extends BaseContractService { async createPayout(dto: CreatePayoutDto) { const { employeeAddress, contractAddress, multiSigWallet } = dto; - console.log('=>(salaries.service.ts:82) employeeAddress', employeeAddress); const ISubmitMultiSig = new ethers.Interface([ 'function payoutInETH(address employee)', ]); diff --git a/chain-api/src/hardhat/test/Salaries.test.ts b/chain-api/src/hardhat/test/Salaries.test.ts new file mode 100644 index 0000000..fc14681 --- /dev/null +++ b/chain-api/src/hardhat/test/Salaries.test.ts @@ -0,0 +1,69 @@ +import { PriceFeedMock, Salaries } from '../../../typechain'; + +const { ethers } = require('hardhat'); +const { expect } = require('chai'); +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; + +describe('Salaries', function () { + let salaries: Salaries; + let owner: SignerWithAddress; + let multisigWallet: SignerWithAddress; + let addr1: SignerWithAddress; + let priceFeedMock: PriceFeedMock; + + beforeEach(async function () { + [owner, multisigWallet, addr1] = await ethers.getSigners(); + + const PriceFeedMockFactory = + await ethers.getContractFactory('PriceFeedMock'); + priceFeedMock = await PriceFeedMockFactory.deploy(); + await priceFeedMock.getDeployedCode(); + // Deploy the Salaries contract + const SalariesFactory = await ethers.getContractFactory('Salaries'); + salaries = (await SalariesFactory.deploy( + multisigWallet.address, + await priceFeedMock.getAddress(), + )) as Salaries; + await salaries.getDeployedCode(); + }); + + it('Should set and get salary correctly', async function () { + await salaries.connect(multisigWallet).setSalary(addr1.address, 1000); + expect(await salaries.getUsdtSalary(addr1.address)).to.equal(1000); + }); + + it('Should payout in ETH correctly', async function () { + // Set the salary in USDT + await salaries.connect(multisigWallet).setSalary(addr1.address, 100); + expect(await salaries.getUsdtSalary(addr1.address)).to.equal(100); + + // Fund the contract with ETH + await owner.sendTransaction({ + to: await salaries.getAddress(), + value: ethers.parseEther('1'), // 1 ETH + }); + + await expect(() => + salaries.connect(multisigWallet).payoutInETH(addr1.address), + ).to.changeEtherBalances( + [salaries, addr1], + ['-32393909944930353', '32393909944930353'], + ); + + // Check events + expect(salaries.connect(multisigWallet).payoutInETH(addr1.address)); + }); +}); + +describe('PriceFeedMock', function () { + it('Should return the mocked price', async function () { + const PriceFeedMockFactory = + await ethers.getContractFactory('PriceFeedMock'); + const priceFeedMock = await PriceFeedMockFactory.deploy(); + await priceFeedMock.getDeployedCode(); + + expect((await priceFeedMock.latestRoundData())[1].toString()).to.equal( + '3087', + ); + }); +}); diff --git a/chain-api/src/provider/provider.service.ts b/chain-api/src/provider/provider.service.ts index 711574c..510ae06 100644 --- a/chain-api/src/provider/provider.service.ts +++ b/chain-api/src/provider/provider.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { ethers } from 'ethers'; import { ConfigService } from '@nestjs/config'; + @Injectable() export class ProviderService { public provider: ethers.JsonRpcProvider; @@ -29,10 +30,9 @@ export class ProviderService { if (!this.provider) { await this.getProvider(); } - const signer = new ethers.Wallet( + return new ethers.Wallet( this.configService.getOrThrow('POLYGON_PK'), this.provider, ); - return signer; } }