Skip to content

Commit

Permalink
added methods to add and remove supported tokens from the contract
Browse files Browse the repository at this point in the history
  • Loading branch information
yashgo0018 committed Nov 30, 2023
1 parent ad6f955 commit 82e6975
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 10 deletions.
89 changes: 79 additions & 10 deletions contracts/FundManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.20;
import {FunctionsClient} from "@chainlink/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsClient.sol";
import {FunctionsRequest} from "@chainlink/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsRequest.sol";

import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract FundManager is Ownable, FunctionsClient {
Expand All @@ -16,17 +17,24 @@ contract FundManager is Ownable, FunctionsClient {
uint32 gasLimit;
bytes encryptedSecretsUrls;

event CircuitAdded(string circuitQASM, bytes32 circuitHash);
event CircuitJobSent(bytes32 circuitHash, string jobId);
event CircuitResultAsked(bytes32 circuitHash, string jobId);
event CircuitResultUpdated(
bytes32 circuitHash,
string jobId,
string result
);
struct Token {
uint256 id;
string symbol;
address contractAddress;
bool isActive;
}

mapping(uint256 => Token) public tokens;
mapping(address => uint256) public tokenAddressToId;

uint256 totalTokens;
uint256 totalTokenIds;
uint256[] public activeTokenIds;

event ChainlinkResponse(bytes32 requestId, bytes response, bytes err);
event SourceUpdatedForAddingCircuit(string sourceForAddingCircuit);
event SourceUpdatedForFetchingResult(string sourceForFetchingResult);

error TokenAlreadyAdded();
error TokenNotFound();

error InvalidValueSent();
error CircuitAlreadyInSystem();
Expand All @@ -39,6 +47,67 @@ contract FundManager is Ownable, FunctionsClient {
address chainlinkFunctionsRouter
) FunctionsClient(chainlinkFunctionsRouter) Ownable(msg.sender) {}

function addToken(
address tokenContractAddress,
string calldata symbol
) public onlyOwner {
uint256 previousTokenId = tokenAddressToId[tokenContractAddress];
if (tokens[previousTokenId].isActive) revert TokenAlreadyAdded();

uint256 tokenId = ++totalTokenIds;
totalTokens++;

tokens[tokenId] = Token({
id: tokenId,
symbol: symbol,
contractAddress: tokenContractAddress,
isActive: true
});
activeTokenIds.push(tokenId);
tokenAddressToId[tokenContractAddress] = tokenId;
}

function removeToken(address tokenContractAddress) public onlyOwner {
uint256 tokenId = tokenAddressToId[tokenContractAddress];
if (!tokens[tokenId].isActive) revert TokenNotFound();

// TODO: sell all the positions for this token and buy for other tokens

tokens[tokenId].isActive = false;

for (uint256 i = 0; i < totalTokens; i++) {
if (activeTokenIds[i] == tokenId) {
activeTokenIds[i] = activeTokenIds[totalTokens - 1];
break;
}
}
activeTokenIds.pop();

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, ",");
}
}
output = string.concat(output, "]}");

return output;
}

function setSubscriptionId(uint64 _subscriptionId) public onlyOwner {
subscriptionId = _subscriptionId;
}
Expand Down
42 changes: 42 additions & 0 deletions test/Lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,48 @@ describe("Fund Manager", function () {
console.log(await fundManager.read.result());
});

it("Should add a token in the contract", async () => {
await fundManager.write.addToken([accounts[1].address, "ethereum"]);

const tokenList = JSON.parse(
await fundManager.read.getJSONTokenSymbolList()
);

expect(tokenList).to.deep.eq({
tokens: [{ id: 1, symbol: "ethereum" }],
});
});

it("Should not add the token again in the contract if already there", async () => {
await expect(
fundManager.write.addToken([accounts[1].address, "ethereum"])
).to.be.rejectedWith("TokenAlreadyAdded");
});

it("Should remove a token from the contract", async () => {
await fundManager.write.removeToken([accounts[1].address]);

const tokenList = JSON.parse(
await fundManager.read.getJSONTokenSymbolList()
);

expect(tokenList).to.deep.eq({
tokens: [],
});
});

it("Should be able to add a token in the contract after it was removed", async () => {
await fundManager.write.addToken([accounts[1].address, "ethereum"]);

const tokenList = JSON.parse(
await fundManager.read.getJSONTokenSymbolList()
);

expect(tokenList).to.deep.eq({
tokens: [{ id: 2, symbol: "ethereum" }],
});
});

// We define a fixture to reuse the same setup in every test.
// We use loadFixture to run this setup once, snapshot that state,
// and reset Hardhat Network to that snapshot in every test.
Expand Down

0 comments on commit 82e6975

Please sign in to comment.