Skip to content

Commit

Permalink
added functions to update the secrets and also paginated the token list
Browse files Browse the repository at this point in the history
  • Loading branch information
yashgo0018 committed Dec 3, 2023
1 parent db1c0df commit 9b4079c
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 34 deletions.
138 changes: 104 additions & 34 deletions contracts/FundManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@ import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract FundManager is Ownable, FunctionsClient {
// chainlink config
using FunctionsRequest for FunctionsRequest.Request;

uint8 public donHostedSecretsSlotID;
uint64 public donHostedSecretsVersion;
bytes32 public donId;
uint64 subscriptionId;
uint32 gasLimit;
bytes encryptedSecretsUrls;
uint32 gasLimitForPriceFetchFunction;
uint32 gasLimitForAssetOptimizationFunction;
bytes encryptedSecretsUrlsForPriceFetchFunction;
bytes encryptedSecretsUrlsForAssetOptimizationFunction;

// chainlink functions
string public priceFetchSourceCode;

// tokens config
struct Token {
uint256 id;
string symbol;
Expand All @@ -31,6 +38,24 @@ contract FundManager is Ownable, FunctionsClient {
uint256 totalTokenIds;
uint256[] public activeTokenIds;

// refresh requests
struct RefreshRequest {
uint256 id;
uint256 totalBatches;
uint256 totalBatchesFulfilled;
bool fulfilled;
}
uint256 public totalRefreshRequests;
mapping(uint256 => RefreshRequest) public refreshRequests;
mapping(uint256 => bytes32[]) public refreshRequestIds;
struct RequestStatus {
uint256 refreshRequestId;
uint256 index;
bool fulfilled;
string dataHash;
}
mapping(bytes32 => RequestStatus) public requestStatuses;

event ChainlinkResponse(bytes32 requestId, bytes response, bytes err);

error TokenAlreadyAdded();
Expand Down Expand Up @@ -86,26 +111,79 @@ contract FundManager is Ownable, FunctionsClient {
totalTokens--;
}

function getJSONTokenSymbolList() public view returns (string memory) {
string memory output = '{"tokens":[';
for (uint256 i = 0; i < totalTokens; i++) {
uint256 tokenId = activeTokenIds[i];
Token memory token = tokens[tokenId];
output = string.concat(
output,
'{"id": ',
Strings.toString(tokenId),
', "symbol": "',
token.symbol,
'"}'
);
if (i != totalTokens - 1) {
output = string.concat(output, ",");
function getJSONTokenSymbolList(
uint256 limit
) public view returns (string[] memory) {
uint256 pages = totalTokens / limit;
if (totalTokens % limit != 0) {
pages += 1;
}

string[] memory outputStrings = new string[](pages);
for (uint256 pageId = 0; pageId < pages; pageId++) {
string memory output = '{"tokens":[';
uint256 upperBound = min((pageId + 1) * limit, totalTokens);
for (uint256 i = pageId * limit; i < upperBound; i++) {
uint256 tokenId = activeTokenIds[i];
Token memory token = tokens[tokenId];
output = string.concat(
output,
'{"id": ',
Strings.toString(tokenId),
', "symbol": "',
token.symbol,
'"}'
);
if (i != upperBound - 1) {
output = string.concat(output, ",");
}
}
output = string.concat(output, "]}");
outputStrings[pageId] = output;
}
output = string.concat(output, "]}");

return output;
return outputStrings;
}

function min(uint256 a, uint256 b) public pure returns (uint256) {
if (a < b) return a;
return b;
}

function setPriceFetchSourceCode(
string calldata _priceFetchSourceCode
) public onlyOwner {
priceFetchSourceCode = _priceFetchSourceCode;
}

function initiateProportionRefresh() public {
string[] memory symbolsPaginated = getJSONTokenSymbolList(4);

uint256 refreshId = ++totalRefreshRequests;
refreshRequests[refreshId] = RefreshRequest({
id: refreshId,
totalBatches: symbolsPaginated.length,
totalBatchesFulfilled: 0,
fulfilled: false
});

for (uint256 i = 0; i < symbolsPaginated.length; i++) {
string[] memory args = new string[](1);
args[0] = symbolsPaginated[i];
bytes32 requestId = sendRequest(
priceFetchSourceCode,
args,
encryptedSecretsUrlsForPriceFetchFunction,
gasLimitForPriceFetchFunction
);
refreshRequestIds[refreshId].push(requestId);
requestStatuses[requestId] = RequestStatus({
refreshRequestId: refreshId,
index: i,
fulfilled: false,
dataHash: ""
});
}
}

function setSubscriptionId(uint64 _subscriptionId) public onlyOwner {
Expand All @@ -122,30 +200,22 @@ contract FundManager is Ownable, FunctionsClient {
donId = _donId;
}

function setEncryptedSecretUrls(
function setEncryptedSecretUrlsForPriceFetchFunction(
bytes calldata _encryptedSecretsUrls
) public onlyOwner {
encryptedSecretsUrls = _encryptedSecretsUrls;
}

function setGasLimit(uint32 _gasLimit) public onlyOwner {
gasLimit = _gasLimit;
encryptedSecretsUrlsForPriceFetchFunction = _encryptedSecretsUrls;
}

function makeRequest(string calldata sourceCode) public payable {
// bytes32 circuitHash = keccak256(abi.encode(circuitQASM));
// if (status[circuitHash] != Status.NON_EXISTENT) revert CircuitAlreadyInSystem();
// if (calculateCost(circuitQASM) != msg.value) revert InvalidValueSent();

// send the request to chainlink
string[] memory args = new string[](1);
args[0] = "Hello World";
sendRequest(sourceCode, args, gasLimit);
function setGasLimitForPriceFetchFunction(
uint32 _gasLimit
) public onlyOwner {
gasLimitForPriceFetchFunction = _gasLimit;
}

function sendRequest(
string memory source,
string[] memory args,
bytes memory encryptedSecretsUrls,
// bytes[] memory bytesArgs,
uint32 gasLimit
) internal returns (bytes32 requestId) {
Expand Down
4 changes: 4 additions & 0 deletions contracts/interfaces/IFunctionsCoordinator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {IFunctionsCoordinator} from "@chainlink/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsCoordinator.sol";
52 changes: 52 additions & 0 deletions scripts/updateSecretsForPriceFetchFunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { viem } from "hardhat";
import { generateAndUploadEncryptedFile } from "../utils/generateAndUploadEncryptedFile";
import {
Account,
Chain,
GetContractReturnType,
PublicClient,
Transport,
WalletClient,
getContract,
} from "viem";
import { abi as FundManagerABI } from "../artifacts/contracts/FundManager.sol/FundManager.json";
import { FundManager$Type } from "../artifacts/contracts/FundManager.sol/FundManager";

const routerAddress = "0x6E2dc0F9DB014aE19888F539E59285D2Ea04244C";
const donId = "fun-polygon-mumbai-1";
const fundManagerAddress = "0x";

async function main() {
const walletClient = (await viem.getWalletClients())[0];
const publicClient = await viem.getPublicClient();

const pinataAPIKey = process.env.PINATA_API_KEY || "";

const encryptedSecretsUrls = await generateAndUploadEncryptedFile({
walletClient,
donId,
routerAddress,
secrets: {
pinataApiKey: pinataAPIKey,
},
});

const fundManager = getContract({
abi: FundManagerABI,
address: fundManagerAddress,
walletClient: walletClient,
publicClient: publicClient,
}) as unknown as GetContractReturnType<
FundManager$Type["abi"],
PublicClient<Transport, Chain>,
WalletClient<Transport, Chain, Account>
>;

await fundManager.write.setEncryptedSecretUrlsForPriceFetchFunction([
encryptedSecretsUrls,
]);

console.log(encryptedSecretsUrls);
}

main().catch((err) => console.error(err));

0 comments on commit 9b4079c

Please sign in to comment.