Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,22 @@ simulate-don:
setup-functions:
forge script script/FunctionsScript.s.sol:FunctionsScript --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast

deploy-all:
make deploy-madt && \
make deploy-usdt && \
make setup-functions && \
make deploy-vault && \
make send-request

# Interactions with the DON via the DataProvider contract
send-request:
forge script script/Interactions.s.sol:Interactions --sig "sendRequest()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv
forge script script/Interactions.s.sol:Interactions --sig "sendRequest()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vv

get-last-response:
forge script script/Interactions.s.sol:Interactions --sig "getLastResponse()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv
forge script script/Interactions.s.sol:Interactions --sig "getLastResponse()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vv

get-last-error:
cast call $(CONTRACT_ADDRESS) "getLastError()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY)
forge script script/Interactions.s.sol:Interactions --sig "getLastError()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vv

get-last-request-id:
cast call $(CONTRACT_ADDRESS) "getLastRequestId()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY)
Expand All @@ -53,17 +60,24 @@ get-last-request-id:
deploy-madt:
forge script script/DeployMADT.s.sol:DeployMADT --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast

deploy-usdt:
forge script script/DeployMockUSDT.s.sol:DeployMockUSDT --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast

deploy-vault:
forge script script/DeployVault.s.sol:DeployVault --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv
forge script script/DeployVault.s.sol:DeployVault --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vv

# Interactions with the Vault contract
# Deposit collateral
deposit-collateral:
forge script script/VaultInteractions.s.sol:VaultInteractions --sig "depositCollateral()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv
forge script script/VaultInteractions.s.sol:VaultInteractions --sig "depositCollateral()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vv

# Redeem collateral
redeem-collateral:
forge script script/VaultInteractions.s.sol:VaultInteractions --sig "redeemCollateral(uint256)" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv
forge script script/VaultInteractions.s.sol:VaultInteractions --sig "redeemCollateral(uint256)" $(AMOUNT) --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vv

# Rebase
rebase:
forge script script/VaultInteractions.s.sol:VaultInteractions --sig "rebase()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vv

NETWORK_ARGS := --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast

Expand Down
13 changes: 13 additions & 0 deletions don-simulator/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions don-simulator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
},
"dependencies": {
"cbor": "^10.0.3",
"dotenv": "^16.4.7",
"ethers": "^5.7.2"
}
}
36 changes: 36 additions & 0 deletions don-simulator/src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require("dotenv").config();
const Location = {
Inline: 0,
Remote: 1,
DONHosted: 2,
};

const CodeLanguage = {
JavaScript: 0,
};

const ReturnType = {
uint: "uint256",
uint256: "uint256",
int: "int256",
int256: "int256",
string: "string",
bytes: "bytes",
};

// Configure the request by setting the fields below
const requestConfig = {
// Location of source code (only Inline is currently supported)
codeLocation: Location.Inline,
// Optional. Secrets can be accessed within the source code with `secrets.varName` (ie: secrets.apiKey). The secrets object can only contain string values.
secrets: {
exchangeRateApiKey: process.env.EXCH_RATE_KEY ?? "",
currencyApiKey: process.env.CURRENCY_KEY ?? "",
},
// Code language (only JavaScript is currently supported)
codeLanguage: CodeLanguage.JavaScript,
// Expected type of the returned value
expectedReturnType: ReturnType.uint256,
};

module.exports = requestConfig;
32 changes: 31 additions & 1 deletion don-simulator/src/localFunctionsTestnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import type {
FunctionsContracts,
RequestEventData,
} from "./types";
import path from "path";

export const startLocalFunctionsTestnet = async (
coordinatorAddress?: string,
Expand All @@ -39,6 +40,23 @@ export const startLocalFunctionsTestnet = async (
): Promise<LocalFunctionsTestnet> => {
const provider = new providers.JsonRpcProvider(`http://localhost:${port}`);

// Add error handler for provider disconnection
provider.on("error", async (error) => {
console.log("Provider error detected, shutting down testnet...");
// Clean up event listeners and close connections
await close();
process.exit(1);
});

// Add network change handler
provider.on("network", async (newNetwork, oldNetwork) => {
if (oldNetwork) {
console.log("Network connection lost, shutting down testnet...");
await close();
process.exit(1);
}
});

const admin = new Wallet(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
provider
Expand Down Expand Up @@ -100,9 +118,14 @@ export const startLocalFunctionsTestnet = async (
const getFunds: GetFunds = async () => {};

const close = async (): Promise<void> => {
// Remove all event listeners
contracts.functionsMockCoordinatorContract.removeAllListeners(
"OracleRequest"
);
provider.removeAllListeners();

// Optional: Add any additional cleanup needed
console.log("Local Functions testnet shut down successfully");
};

return {
Expand Down Expand Up @@ -494,8 +517,15 @@ if (require.main === module) {
try {
const args = process.argv.slice(2);
const coordinatorAddress = args[0];
const configPath = path.join(
process.cwd(),
"don-simulator/src/config.js"
);
console.log("Starting local Functions testnet...");
const testnet = await startLocalFunctionsTestnet(coordinatorAddress);
const testnet = await startLocalFunctionsTestnet(
coordinatorAddress,
configPath
);
console.log("Local Functions testnet started successfully");

// Keep the process running
Expand Down
53 changes: 51 additions & 2 deletions don-simulator/src/source/source.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
return Functions.encodeUint256(0.1 * 100);

// // Discontinued because of API changes.
// // const bkamAPI = Functions.makeHttpRequest({
// // url: `https://api.centralbankofmorocco.ma/cours/Version1/api/CoursVirement?libDevise=USD`,
// // headers: { "Ocp-Apim-Subscription-Key": secrets.BKAM_KEY },
// // })

// if (secrets.exchangeRateApiKey.length === 0) {
// throw Error("No valid EXCH_RATE_KEY was supplied");
// }

// if (secrets.currencyApiKey.length === 0) {
// throw Error("No valid CURRENCY_KEY was supplied");
// }

// const exchRateAPI = Functions.makeHttpRequest({
// url: `https://v6.exchangerate-api.com/v6/${secrets.exchangeRateApiKey}/pair/MAD/USD`,
// });

// const currencyAPI = Functions.makeHttpRequest({
// url: `https://api.currencyapi.com/v3/latest?apikey=${secrets.currencyApiKey}&currencies=USD&base_currency=MAD`,
// });

// const [exchRateAPIResponse, currencyAPIResponse] = await Promise.all([
// exchRateAPI,
// currencyAPI,
// ]);

// const prices = [];
// if (!exchRateAPIResponse.error) {
// prices.push(exchRateAPIResponse.data.conversion_rate);
// } else {
// console.log("ExchangeRateAPI Error");
// throw Error(JSON.stringify(exchRateAPIResponse));
// }
// if (!currencyAPIResponse.error) {
// prices.push(currencyAPIResponse.data.data.USD.value);
// } else {
// console.log("CurrencyAPI Error");
// throw Error(JSON.stringify(currencyAPIResponse));
// }

// if (prices.length < 2) {
// // If an error is thrown, it will be returned back to the smart contract
// throw Error("More than 1 API failed");
// }

// const medianRate = prices.sort((a, b) => a - b)[Math.round(prices.length / 2)];
// console.log(`Median MAD rate: $${medianRate.toFixed(2)}`);

// return Functions.encodeUint256(Math.round(medianRate * 100));
return Functions.encodeUint256(11);
3 changes: 3 additions & 0 deletions don-simulator/src/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require("dotenv").config();

console.log(process.env.EXCH_RATE_KEY);
13 changes: 13 additions & 0 deletions script/DeployMockUSDT.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Script} from "forge-std/Script.sol";
import {MockUSDT} from "../src/MockUSDT.sol";

contract DeployMockUSDT is Script {
function run() public {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
new MockUSDT();
vm.stopBroadcast();
}
}
14 changes: 7 additions & 7 deletions script/DeployVault.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {DevOpsTools} from "lib/foundry-devops/src/DevOpsTools.sol";

contract DeployVault is Script, HelperConfig {
IDataProvider public dataProvider;
address contractAddress = DevOpsTools.get_most_recent_deployment("DataProvider", block.chainid);
address MADTAddress = DevOpsTools.get_most_recent_deployment("MADT", block.chainid);
function run() public {
address contractAddress = DevOpsTools.get_most_recent_deployment("DataProvider", block.chainid);
address MADTAddress = DevOpsTools.get_most_recent_deployment("MADT", block.chainid);

MADT public madt = MADT(MADTAddress);
MADT madt = MADT(MADTAddress);

function run() public {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
dataProvider = IDataProvider(contractAddress);
console.log("Deploying Vault..");
IDataProvider dataProvider = IDataProvider(contractAddress);
IERC20 usdt = IERC20(getNetworkConfig().usdToken);
Vault vault = new Vault(dataProvider, madt, usdt);
// madt.setVault(address(vault));
madt.setVault(address(vault));
vm.stopBroadcast();
}
}
6 changes: 3 additions & 3 deletions script/HelperConfig.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";

import {MockUSDT} from "../src/MockUSDT.sol";
import {DevOpsTools} from "lib/foundry-devops/src/DevOpsTools.sol";

contract HelperConfig is Script {
// If we are on a local chain, we deploy the mock contract
// Otherwise, we fetch the existing address from the live network

uint256 public constant ETH_SEPOLIA_CHAIN_ID = 11155111;
address public usdtAddress = DevOpsTools.get_most_recent_deployment("MockUSDT", block.chainid);

struct NetworkConfig {
address linkToken;
Expand Down Expand Up @@ -46,11 +48,9 @@ contract HelperConfig is Script {
}

function getAnvilEthConfig() public returns (NetworkConfig memory anvilConfig) {
MockUSDT usdt = new MockUSDT();

anvilConfig = NetworkConfig({
linkToken: vm.envAddress("LINK_TOKEN_ADDRESS"),
usdToken: address(usdt),
usdToken: usdtAddress,
subscriptionId: 1,
donId: stringToBytes32(vm.envString("DON_ID")),
router: vm.envAddress("FUNCTIONS_ROUTER_ADDRESS"),
Expand Down
4 changes: 2 additions & 2 deletions script/Interactions.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ contract Interactions is Script, HelperConfig {
function getLastResponse() public returns (uint256) {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
dataProvider = IDataProvider(contractAddress);
bytes memory response = dataProvider.getLastResponse();
return abi.decode(response, (uint256));
uint256 madValue = dataProvider.getMADValueInUSD();
vm.stopBroadcast();
return madValue;
}

function sendRequest() public {
Expand Down
17 changes: 16 additions & 1 deletion script/VaultInteractions.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,31 @@ import {IDataProvider} from "../src/interfaces/IDataProvider.sol";
import {FunctionsScript} from "./FunctionsScript.s.sol";
import {Vault} from "../src/Vault.sol";
import {DevOpsTools} from "lib/foundry-devops/src/DevOpsTools.sol";
import {MockUSDT} from "../src/MockUSDT.sol";

contract VaultInteractions is Script, HelperConfig {
IDataProvider public dataProvider;
address contractAddress = DevOpsTools.get_most_recent_deployment("Vault", block.chainid);

Vault public vault = Vault(contractAddress);
MockUSDT public usdt = MockUSDT(usdtAddress);

function depositCollateral() public {
vm.startBroadcast();
vault.depositCollateral(100);
usdt.approve(contractAddress, 100000000000000000000000000000);
vault.depositCollateral(12500);
vm.stopBroadcast();
}

function redeemCollateral(uint256 amountInUsd) public {
vm.startBroadcast();
vault.redeemCollateral(amountInUsd);
vm.stopBroadcast();
}

function rebase() public {
vm.startBroadcast();
vault.rebase();
vm.stopBroadcast();
}
}
Loading
Loading