Skip to content

Commit

Permalink
Update state after loops when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
shanejearley committed Aug 22, 2023
1 parent 5c98473 commit 4d9ea1d
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 91 deletions.
4 changes: 2 additions & 2 deletions contracts/ethereum/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const forkConfig = { url: forkUrl, blockNumber: parseInt(process.env.ETHEREUM_FO

const externalEnv = {
mainnet: {
ORACLE_ADDRESS: '0x0000000000000000000000000000000000000000',
DAO_ORACLE_ADDRESS: '0x0000000000000000000000000000000000000000',
BEACON_DEPOSIT_ADDRESS: '0x00000000219ab540356cBB839Cbe05303d7705Fa',
LINK_FUNCTIONS_ADDRESS: '0x0000000000000000000000000000000000000000',
LINK_REGISTRAR_ADDRESS: ' 0xDb8e8e2ccb5C033938736aa89Fe4fa1eDfD15a1d',
Expand All @@ -42,7 +42,7 @@ const externalEnv = {
WETH_TOKEN_ADDRESS: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
},
goerli: {
ORACLE_ADDRESS: '0x0000000000000000000000000000000000000000',
DAO_ORACLE_ADDRESS: '0x0000000000000000000000000000000000000000',
BEACON_DEPOSIT_ADDRESS: '0x07b39F4fDE4A38bACe212b546dAc87C58DfE3fDC',
LINK_FUNCTIONS_ADDRESS: '0x0000000000000000000000000000000000000000',
LINK_REGISTRAR_ADDRESS: '0x57A4a13b35d25EE78e084168aBaC5ad360252467',
Expand Down
2 changes: 1 addition & 1 deletion contracts/ethereum/scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ethers } from 'hardhat'
*/
void async function () {
const managerArgs = {
oracleAddress: process.env.ORACLE_ADDRESS,
daoOracleAddress: process.env.DAO_ORACLE_ADDRESS,
beaconDepositAddress: process.env.BEACON_DEPOSIT_ADDRESS,
linkFunctionsAddress: process.env.LINK_FUNCTIONS_ADDRESS,
linkRegistrarAddress: process.env.LINK_REGISTRAR_ADDRESS,
Expand Down
8 changes: 4 additions & 4 deletions contracts/ethereum/scripts/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { PoolStatus } from '@casimir/types'
* Deploy contracts to local network and run local events and oracle handling
*/
void async function () {
const [, , , , fourthUser, keeper, oracle] = await ethers.getSigners()
const [, , , , fourthUser, keeper, daoOracle] = await ethers.getSigners()

const preregisteredOperatorIds = process.env.PREREGISTERED_OPERATOR_IDS?.split(',').map(id => parseInt(id)) || [654, 655, 656, 657]
if (preregisteredOperatorIds.length < 4) throw new Error('Not enough operator ids provided')
Expand All @@ -24,7 +24,7 @@ void async function () {
console.log(`MockFunctionsOracle contract deployed to ${mockFunctionsOracle.address}`)

const managerArgs = {
oracleAddress: oracle.address,
daoOracleAddress: daoOracle.address,
beaconDepositAddress: process.env.BEACON_DEPOSIT_ADDRESS,
linkFunctionsAddress: mockFunctionsOracle.address,
linkRegistrarAddress: process.env.LINK_REGISTRAR_ADDRESS,
Expand Down Expand Up @@ -161,8 +161,8 @@ void async function () {
const depositAmount = 32 * ((100 + await manager.feePercent()) / 100)
const stake = await manager.connect(fourthUser).depositStake({ value: ethers.utils.parseEther(depositAmount.toString()) })
await stake?.wait()
// Todo handle in oracle
await depositUpkeepBalanceHandler({ manager, signer: oracle })
// Todo handle in DAO oracle
await depositUpkeepBalanceHandler({ manager, signer: daoOracle })
}, 2500)

run('npm run dev --workspace @casimir/oracle')
Expand Down
53 changes: 38 additions & 15 deletions contracts/ethereum/src/v1/CasimirManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";
import "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";

import 'hardhat/console.sol';

/**
* @title Manager contract that accepts and distributes deposits
*/
Expand Down Expand Up @@ -49,7 +51,7 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
/** Compound minimum (0.1 ETH) */
uint256 private constant COMPOUND_MINIMUM = 100000000 gwei;
/** Minimum balance for upkeep registration (0.1 LINK) */
uint256 private constant upkeepRegistrationMinimum = 100000000 gwei;
uint256 private constant UPKEEP_REGISTRATION_MINIMUM = 100000000 gwei;
/** Scale factor for each rewards to stake ratio */
uint256 private constant SCALE_FACTOR = 1 ether;
/** Uniswap 0.3% fee tier */
Expand All @@ -61,7 +63,7 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
/* Immutable */
/*************/

/** Manager oracle address */
/** DAO oracle address */
address private immutable oracleAddress;
/** Registry contract */
ICasimirRegistry private immutable registry;
Expand Down Expand Up @@ -203,7 +205,7 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {

/**
* @notice Constructor
* @param _oracleAddress The manager oracle address
* @param daoOracleAddress The DAO oracle address
* @param beaconDepositAddress The Beacon deposit address
* @param linkFunctionsAddress The Chainlink functions oracle address
* @param linkRegistrarAddress The Chainlink keeper registrar address
Expand All @@ -217,7 +219,7 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
* @param wethTokenAddress The WETH contract address
*/
constructor(
address _oracleAddress,
address daoOracleAddress,
address beaconDepositAddress,
address linkFunctionsAddress,
address linkRegistrarAddress,
Expand All @@ -230,7 +232,18 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
address swapRouterAddress,
address wethTokenAddress
) {
oracleAddress = _oracleAddress;
require(daoOracleAddress != address(0), "Missing oracle address");
require(beaconDepositAddress != address(0), "Missing beacon deposit address");
require(linkRegistrarAddress != address(0), "Missing link registrar address");
require(linkRegistryAddress != address(0), "Missing link registry address");
require(linkTokenAddress != address(0), "Missing link token address");
require(ssvNetworkAddress != address(0), "Missing SSV network address");
require(ssvTokenAddress != address(0), "Missing SSV token address");
require(swapFactoryAddress != address(0), "Missing Uniswap factory address");
require(swapRouterAddress != address(0), "Missing Uniswap router address");
require(wethTokenAddress != address(0), "Missing WETH token address");

oracleAddress = daoOracleAddress;
beaconDeposit = IDepositContract(beaconDepositAddress);
linkRegistrar = KeeperRegistrarInterface(linkRegistrarAddress);
linkRegistry = AutomationRegistryInterface(linkRegistryAddress);
Expand Down Expand Up @@ -369,7 +382,7 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
);
linkToken.approve(address(linkRegistrar), linkAmount);
if (upkeepId == 0) {
if (linkAmount < upkeepRegistrationMinimum) {
if (linkAmount < UPKEEP_REGISTRATION_MINIMUM) {
revert("Upkeep registration minimum not met");
}
upkeepId = linkRegistrar.registerUpkeep(
Expand Down Expand Up @@ -565,6 +578,8 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
* @param count The number of withdrawals to complete
*/
function fulfillWithdrawals(uint256 count) external onlyUpkeep {
uint256 withdrawalAmount;
uint256 withdrawalCount;
while (count > 0) {
count--;
if (requestedWithdrawalQueue.length == 0) {
Expand All @@ -575,11 +590,13 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
break;
}
requestedWithdrawalQueue.remove(0);
requestedWithdrawalBalance -= withdrawal.amount;
requestedWithdrawals--;
withdrawalAmount += withdrawal.amount;
withdrawalCount++;

fulfillWithdrawal(withdrawal.user, withdrawal.amount);
}
requestedWithdrawalBalance -= withdrawalAmount;
requestedWithdrawals -= withdrawalCount;
}

/**
Expand All @@ -588,6 +605,8 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
* @param amount The withdrawal amount
*/
function fulfillWithdrawal(address sender, uint256 amount) private {
require(sender != address(0), "Missing sender");

if (amount <= exitedBalance) {
exitedBalance -= amount;
} else {
Expand Down Expand Up @@ -798,6 +817,8 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
* @param poolIds The pool IDs
*/
function reportForcedExits(uint32[] memory poolIds) external onlyOracle {
uint256 newForcedExits;
uint256 newRequestedExits;
for (uint256 i = 0; i < poolIds.length; i++) {
uint32 poolId = poolIds[i];
ICasimirPool pool = ICasimirPool(poolAddresses[poolId]);
Expand All @@ -807,12 +828,14 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
"Forced exit already reported"
);

forcedExits++;
newForcedExits++;
if (poolDetails.status == ICasimirPool.PoolStatus.EXITING_REQUESTED) {
requestedExits--;
newRequestedExits++;
}
pool.setStatus(ICasimirPool.PoolStatus.EXITING_FORCED);
}
forcedExits += newForcedExits;
requestedExits -= newRequestedExits;

emit ForcedExitsReported(poolIds);
}
Expand Down Expand Up @@ -1031,13 +1054,13 @@ contract CasimirManager is ICasimirManager, Ownable, ReentrancyGuard {
}

/**
* @notice Update the functions oracle address
* @param functionsAddress New functions oracle address
* @notice Set a new functions oracle address
* @param newFunctionsAddress New functions oracle address
*/
function setFunctionsAddress(address functionsAddress) external onlyOwner {
upkeep.setOracleAddress(functionsAddress);
function setFunctionsAddress(address newFunctionsAddress) external onlyOwner {
upkeep.setFunctionsAddress(newFunctionsAddress);

emit FunctionsAddressSet(functionsAddress);
emit FunctionsAddressSet(newFunctionsAddress);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions contracts/ethereum/src/v1/CasimirPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ contract CasimirPool is ICasimirPool, Ownable, ReentrancyGuard {
bytes memory _publicKey,
uint64[] memory _operatorIds
) {
require(registryAddress != address(0), "Missing registry address");

manager = ICasimirManager(msg.sender);
registry = ICasimirRegistry(registryAddress);
id = _id;
Expand Down
2 changes: 2 additions & 0 deletions contracts/ethereum/src/v1/CasimirRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ contract CasimirRegistry is ICasimirRegistry, Ownable {
* @param ssvNetworkViewsAddress The SSV network views address
*/
constructor(address ssvNetworkViewsAddress) {
require(ssvNetworkViewsAddress != address(0), "Missing SSV network views address");

manager = ICasimirManager(msg.sender);
ssvNetworkViews = ISSVNetworkViews(ssvNetworkViewsAddress);
}
Expand Down
40 changes: 26 additions & 14 deletions contracts/ethereum/src/v1/CasimirUpkeep.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {Functions, FunctionsClient} from "@chainlink/contracts/src/v0.8/dev/func
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

import 'hardhat/console.sol';

/**
* @title Upkeep contract that automates and handles reports
*/
Expand Down Expand Up @@ -39,11 +41,11 @@ contract CasimirUpkeep is ICasimirUpkeep, FunctionsClient, Ownable {
/** Current report status */
ReportStatus private reportStatus;
/** Current report period */
uint32 reportPeriod;
uint32 private reportPeriod;
/** Current report remaining request count */
uint256 reportRemainingRequests;
uint256 private reportRemainingRequests;
/** Current report block */
uint256 reportRequestBlock;
uint256 private reportRequestBlock;
/** Current report request timestamp */
uint256 private reportTimestamp;
/** Current report swept balance */
Expand All @@ -57,19 +59,19 @@ contract CasimirUpkeep is ICasimirUpkeep, FunctionsClient, Ownable {
/** Current report completed exits */
uint256 private reportCompletedExits;
/** Current report compoundable pools */
uint32[5] reportCompoundablePoolIds;
uint32[5] private reportCompoundablePoolIds;
/** Finalizable activated deposits */
uint256 private finalizableActivatedDeposits;
/** Finalizable compoundable pools */
uint32[5] finalizableCompoundablePoolIds;
uint32[5] private finalizableCompoundablePoolIds;
/** Current report request */
mapping(bytes32 => RequestType) private reportRequests;
/** Current report response error */
bytes private reportResponseError;
/** Binary request source code */
bytes public requestCBOR;
/** Fulfillment gas limit */
uint32 fulfillGasLimit;
uint32 private fulfillGasLimit;
/** Functions subscription ID (Mocked until managed subscriptions are implemented) */
uint64 private linkSubscriptionId = 1;

Expand All @@ -79,11 +81,16 @@ contract CasimirUpkeep is ICasimirUpkeep, FunctionsClient, Ownable {

/**
* Constructor
* @param linkFunctionsAddress The functions oracle contract address
* @param functionsAddress The functions oracle address
*/
constructor(
address linkFunctionsAddress
) FunctionsClient(linkFunctionsAddress) {
address functionsAddress
) FunctionsClient(functionsAddress) {
require(
functionsAddress != address(0),
"Missing functions address"
);

manager = ICasimirManager(msg.sender);
}

Expand Down Expand Up @@ -259,13 +266,18 @@ contract CasimirUpkeep is ICasimirUpkeep, FunctionsClient, Ownable {
}

/**
* @notice Update the functions oracle address
* @param newOracleAddress New oracle address
* @notice Set a new functions oracle address
* @param newFunctionsAddress New functions oracle address
*/
function setOracleAddress(address newOracleAddress) external onlyOwner {
setOracle(newOracleAddress);
function setFunctionsAddress(address newFunctionsAddress) external onlyOwner {
require (
newFunctionsAddress != address(0),
"Missing functions address"
);

setOracle(newFunctionsAddress);

emit OracleAddressSet(newOracleAddress);
emit FunctionsAddressSet(newFunctionsAddress);
}

// Dev-only functions
Expand Down
3 changes: 3 additions & 0 deletions contracts/ethereum/src/v1/CasimirViews.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ contract CasimirViews is ICasimirViews {
* @param registryAddress The registry address
*/
constructor(address managerAddress, address registryAddress) {
require(managerAddress != address(0), "Missing manager address");
require(registryAddress != address(0), "Missing registry address");

manager = ICasimirManager(managerAddress);
registry = ICasimirRegistry(registryAddress);
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/ethereum/src/v1/interfaces/ICasimirUpkeep.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface ICasimirUpkeep is AutomationCompatibleInterface {
/**********/

event OCRResponse(bytes32 indexed requestId, bytes result, bytes err);
event OracleAddressSet(address oracleAddress);
event FunctionsAddressSet(address functionsAddress);
event RequestSet();
event UpkeepPerformed(ReportStatus indexed status);

Expand All @@ -33,7 +33,7 @@ interface ICasimirUpkeep is AutomationCompatibleInterface {
/*************/

function performUpkeep(bytes calldata performData) external;
function setOracleAddress(address oracleAddress) external;
function setFunctionsAddress(address newFunctionsAddress) external;
function mockFulfillRequest(
bytes32 requestId,
bytes memory result,
Expand Down
Loading

0 comments on commit 4d9ea1d

Please sign in to comment.