license finished

This commit is contained in:
emochka2007 2024-05-21 15:58:49 +03:00
parent 61a74636d1
commit 7809a91416
9 changed files with 248 additions and 35 deletions

View File

@ -5,7 +5,9 @@ import {
DeployLicenseDto,
GetLicenseInfoDto,
GetShareLicense,
LicensePayoutDto,
RequestLicenseDto,
SetPayoutContractDto,
} from './license.dto';
@ApiTags('license')
@Controller('license')
@ -37,7 +39,17 @@ export class LicenseController {
}
@Get('payout-contract')
async getPayoutContract(@Body() dto: GetShareLicense) {
async getPayoutContract(@Body() dto: GetLicenseInfoDto) {
return this.licenseService.getPayoutContract(dto);
}
@Post('payout')
async payout(@Body() dto: LicensePayoutDto) {
return this.licenseService.payout(dto);
}
@Post('set-payout-contract')
async setPayoutContract(@Body() dto: SetPayoutContractDto) {
return this.licenseService.setPayoutContract(dto);
}
}

View File

@ -18,9 +18,6 @@ export class DeployLicenseDto {
})
@IsNumber({}, { each: true })
shares: number[];
@ApiProperty()
@IsString()
payrollAddress: string;
}
export class RequestLicenseDto extends GetLicenseInfoDto {
@ -36,3 +33,10 @@ export class GetShareLicense extends GetLicenseInfoDto {
@ApiProperty()
ownerAddress: string;
}
export class LicensePayoutDto extends RequestLicenseDto {}
export class SetPayoutContractDto extends RequestLicenseDto {
@IsString()
@ApiProperty()
payoutContract: string;
}

View File

@ -5,9 +5,10 @@ import { BaseContractService } from '../../base/base-contract.service';
import {
DeployLicenseDto,
GetLicenseInfoDto,
GetLicenseResponseDto,
GetShareLicense,
LicensePayoutDto,
RequestLicenseDto,
SetPayoutContractDto,
} from './license.dto';
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
import { ProviderService } from '../../base/provider/provider.service';
@ -44,18 +45,16 @@ export class LicenseService extends BaseContractService {
const contract = new ethers.Contract(contractAddress, abi, signer);
const answer: bigint = await contract.request();
const answer: bigint = await contract.totalPayoutInUSD();
console.log('=>(license.service.ts:45) answer', answer);
return answer.toString();
}
async deploy(dto: DeployLicenseDto) {
console.log('=>(license.service.ts:53) dto', dto);
const { multiSigWallet, shares, owners, payrollAddress } = dto;
const { abi, bytecode } = await hre.artifacts.readArtifact(
const { multiSigWallet, shares, owners } = dto;
const { bytecode } = await hre.artifacts.readArtifact(
'StreamingRightsManagement',
);
const signer = await this.providerService.getSigner();
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
@ -68,7 +67,6 @@ export class LicenseService extends BaseContractService {
'address',
'address[]',
'uint[]',
'address',
],
[
CHAINLINK.AMOY.CHAINLINK_TOKEN,
@ -78,7 +76,6 @@ export class LicenseService extends BaseContractService {
multiSigWallet,
owners,
shares,
payrollAddress,
],
);
const fullBytecode = bytecode + abiEncodedConstructorArguments.substring(2);
@ -145,4 +142,36 @@ export class LicenseService extends BaseContractService {
return answer;
}
async payout(dto: LicensePayoutDto) {
const { multiSigWallet, contractAddress } = dto;
const ISubmitMultiSig = new ethers.Interface(['function payout()']);
const data = ISubmitMultiSig.encodeFunctionData('payout');
return await this.multiSigService.submitTransaction({
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
}
async setPayoutContract(dto: SetPayoutContractDto) {
const { multiSigWallet, contractAddress, payoutContract } = dto;
const ISubmitMultiSig = new ethers.Interface([
'function setPayoutContract(address payable)',
]);
const data = ISubmitMultiSig.encodeFunctionData('setPayoutContract', [
payoutContract,
]);
return await this.multiSigService.submitTransaction({
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
}
}

View File

@ -4,7 +4,7 @@ import { IsNumber, IsString } from 'class-validator';
export class SalariesDeployDto {
@ApiProperty()
@IsString()
multiSigWallet: string;
authorizedWallet: string;
}
export class SetSalaryDto {

View File

@ -29,7 +29,7 @@ export class SalariesService extends BaseContractService {
const salaryContract = new ethers.ContractFactory(abi, bytecode, signer);
const myContract = await salaryContract.deploy(
dto.multiSigWallet,
dto.authorizedWallet,
CHAINLINK.AMOY.AGGREGATOR_ADDRESS.USDT_ETH,
);
await myContract.waitForDeployment();

View File

@ -1,10 +1,118 @@
//
//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/
*/
License
sender
receiver
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
*/
contract LinkWellBoolConsumerContractExample is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;
*/
address private oracleAddress;
bytes32 private jobId;
uint256 private fee;
constructor(
address _chainLinkToken,
address _oracleAddress,
string memory _jobId,
uint _fee,
address _multiSigAddress,
address[] memory _owners,
uint[] memory _shares
) ConfirmedOwner(_multiSigAddress) {
_setChainlinkToken(_chainLinkToken);
setOracleAddress(_oracleAddress);
setJobId(_jobId);
setFeeInHundredthsOfLink(_fee);
multisigWallet = _multiSigAddress;
}
constructor() ConfirmedOwner(msg.sender) {
_setChainlinkToken(0x0Fd9e8d3aF1aaee056EB9e802c3A762a667b1904);
setOracleAddress(0xd36c6B1777c7f3Db1B3201bDD87081A9045B7b46);
setJobId("43309009a154495cb2ed794233e6ff56");
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":[{"coin":"BTC","isActive":false},{"coin":"ETH","isActive":false},{"coin":"LINK","isActive":true}]}');
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":[{"coin":"BTC","isActive":false},{"coin":"ETH","isActive":false},{"coin":"LINK","isActive":true}]}'
// PROCESS THE RESULT (example)
req._add('path', 'json,data,2,isActive');
// Send the request to the Chainlink oracle
_sendOperatorRequest(req, fee);
}
bool public response;
// Receive the result from the Chainlink oracle
event RequestFulfilled(bytes32 indexed requestId);
function fulfill(bytes32 requestId, bool data) 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
response = data; // example value: true
}
// 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"
);
}
}

View File

@ -4,14 +4,7 @@ pragma solidity ^0.8.17;
import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import "./Payroll.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 StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;
@ -33,8 +26,7 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
uint _fee,
address _multiSigAddress,
address[] memory _owners,
uint[] memory _shares,
address payable _payoutAddress
uint[] memory _shares
) ConfirmedOwner(_multiSigAddress) {
_setChainlinkToken(_chainLinkToken);
@ -47,7 +39,6 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
multisigWallet = _multiSigAddress;
payoutContract = Payroll(_payoutAddress);
require(_owners.length == _shares.length, "Owners and shares length mismatch");
@ -68,10 +59,20 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
//update share
//change payout address
//
modifier hasValidPayoutContract() {
require(address(payoutContract) != address(0), "payoutContract not initialized");
_;
}
function getShare(address owner) public view returns(uint){
return ownerShare[owner];
}
function setPayoutContract(address payable _payoutAddress) public onlyOwner {
require(_payoutAddress != address(0), "Invalid address: zero address not allowed");
payoutContract = Payroll(_payoutAddress);
}
// Send a request to the Chainlink oracle
function request() external onlyOwner{
@ -90,6 +91,7 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
// PROCESS THE RESULT (example)
req._add('path', 'ETH,USD');
req._addInt('multiplier', 10 ** 18);
// Send the request to the Chainlink oracle
_sendOperatorRequest(req, fee);
}
@ -102,15 +104,16 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
function fulfill(bytes32 requestId, uint256 data) 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
totalPayoutInUSD = data / 100; // example value: 1875870000000000000000 (1875.87 before "multiplier" is applied)
totalPayoutInUSD = data / 1e18 / 100; // example value: 1875870000000000000000 (1875.87 before "multiplier" is applied)
}
function payout() external onlyOwner {
// using arrays to reduce gas
uint[] memory shares;
function payout() external onlyOwner hasValidPayoutContract{
for(uint i=0; i< owners.length; i++){
shares[i] = ownerShare[owners[i]];
// using arrays to reduce gas
uint[] memory shares = new uint[](owners.length);
for(uint i=0; i< owners.length; i++){
shares[i] = ownerShare[owners[i]] * totalPayoutInUSD / 100;
}
payoutContract.oneTimePayout(owners, shares);
}

View File

@ -0,0 +1,57 @@
import { StreamingRightsManagement } from '../../../typechain';
import { CHAINLINK } from '../../config/chainlink.config';
const { expect } = require('chai');
const { ethers } = require('hardhat');
describe('StreamingRightsManagement', function () {
let streamingRightsManagement: StreamingRightsManagement,
payContract,
owner,
addr1,
addr2;
const shares = [25, 25, 50];
beforeEach(async function () {
[owner, addr1, addr2] = await ethers.getSigners();
const Payroll = await ethers.getContractFactory('Payroll');
payContract = await Payroll.deploy(owner.address, owner.address); // assume an oracle price feed address
const StreamingRightsManagement = await ethers.getContractFactory(
'StreamingRightsManagement',
);
streamingRightsManagement = await StreamingRightsManagement.deploy(
CHAINLINK.AMOY.CHAINLINK_TOKEN, // Chainlink Token address
CHAINLINK.AMOY.ORACLE_ADDRESS, // Oracle address
CHAINLINK.AMOY.JOB_IDS.UINT,
0,
owner.address,
[owner.address, addr1.address, addr2.address],
shares,
);
});
describe('Initialization', function () {
it('should set owners and shares correctly', async function () {
expect(await streamingRightsManagement.getShare(owner.address)).to.equal(
25,
);
expect(await streamingRightsManagement.getShare(addr1.address)).to.equal(
25,
);
expect(await streamingRightsManagement.getShare(addr2.address)).to.equal(
50,
);
});
});
describe('Payout Functionality', function () {
it('should successfully call payout', async function () {
await streamingRightsManagement.setPayoutContract(payContract.address);
await expect(streamingRightsManagement.payout()).to.not.be.reverted;
});
});
// More tests as needed for other functions
});