Skip to content
Open
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
Binary file modified defi-automation/sudden-balance-drop-trap/bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions defi-automation/sudden-balance-drop-trap/drosera.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ drosera_address = ""
[traps.sudden_balance_drop]
path = "out/SuddenBalanceDropTrap.sol/SuddenBalanceDropTrap.json"
response_contract = "0x0000000000000000000000000000000000000000" # placeholder - would be response contract address
response_function = "handleBalanceDrop(address,uint256,uint256)" # function to handle sudden balance drops
response_function = "handleBalanceDropWithEvent(address,uint256,uint256)" # function to handle sudden balance drops
cooldown_period_blocks = 50
min_number_of_operators = 2
min_number_of_operators = 1
max_number_of_operators = 5
block_sample_size = 1
private_trap = false
block_sample_size = 2
private_trap = true
whitelist = []
address = "0x0000000000000000000000000000000000000000" # placeholder - would be deployed trap address
3 changes: 2 additions & 1 deletion defi-automation/sudden-balance-drop-trap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"forge-std": "github:foundry-rs/forge-std#v1.8.1"
},
"dependencies": {
"contracts": "https://github.com/drosera-network/contracts"
"contracts": "https://github.com/drosera-network/contracts",
"solmate": "^6.8.0"
}
}
3 changes: 2 additions & 1 deletion defi-automation/sudden-balance-drop-trap/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
forge-std/=node_modules/forge-std/src/
drosera-contracts/=node_modules/contracts/src/
drosera-contracts/=node_modules/contracts/src/
solmate/=node_modules/solmate/
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface ISecuredVault {
function pause() external;
function activateCircuitBreaker() external;
function emergencyTransferToOwner() external;
}

/**
* @title SuddenBalanceDropResponse
* @notice Response contract for handling sudden balance drop alerts
Expand All @@ -12,6 +18,9 @@ contract SuddenBalanceDropResponse {
uint256 newBalance,
uint256 timestamp
);
event VaultPaused(address indexed vault);
event CircuitBreakerActivated(address indexed vault);
event EmergencyTransferTriggered(address indexed vault);

// State to track responses
mapping(address => bool) public balanceDropHandled;
Expand All @@ -29,20 +38,92 @@ contract SuddenBalanceDropResponse {
}

/**
* @notice Handle a sudden balance drop
* @notice Handle a sudden balance drop - Event only
* @param vault The vault address that experienced the drop
* @param oldBalance The previous balance
* @param newBalance The current balance
* @dev This only emits an event for monitoring purposes
*/
function handleBalanceDropWithEvent(
address vault,
uint256 oldBalance,
uint256 newBalance
) external onlyTrapConfig {
// Mark the vault as handled
balanceDropHandled[vault] = true;
emit BalanceDropHandled(vault, oldBalance, newBalance, block.timestamp);
}

/**
* @notice Handle a sudden balance drop - Pause vault
* @param vault The vault address that experienced the drop
* @param oldBalance The previous balance
* @param newBalance The current balance
* @dev This emits an event and attempts to pause the vault
*/
function handleBalanceDropWithPause(
address vault,
uint256 oldBalance,
uint256 newBalance
) external onlyTrapConfig {
// Mark the vault as handled
balanceDropHandled[vault] = true;
emit BalanceDropHandled(vault, oldBalance, newBalance, block.timestamp);

// Attempt to pause the vault if it supports pausing
try ISecuredVault(vault).pause() {
emit VaultPaused(vault);
} catch {
// Vault doesn't support pausing or pause failed
}
}

/**
* @notice Activate circuit breaker for a vault (alternative to pausing)
* @param vault The vault address that experienced the drop
* @param oldBalance The previous balance
* @param newBalance The current balance
* @dev This provides a time-based freeze instead of indefinite pause
*/
function handleBalanceDropWithCircuitBreaker(
address vault,
uint256 oldBalance,
uint256 newBalance
) external onlyTrapConfig {
// Mark the vault as handled
balanceDropHandled[vault] = true;
emit BalanceDropHandled(vault, oldBalance, newBalance, block.timestamp);

// Activate the vault's circuit breaker
try ISecuredVault(vault).activateCircuitBreaker() {
emit CircuitBreakerActivated(vault);
} catch {
// Vault doesn't support circuit breaker or activation failed
}
}

/**
* @notice Transfer all vault funds to owner (emergency protection)
* @param vault The vault address that experienced the drop
* @param oldBalance The previous balance
* @param newBalance The current balance
* @dev This function matches the response_function signature in drosera.toml
* @dev This transfers all remaining funds to vault owner
*/
function handleBalanceDrop(
function handleBalanceDropWithTransfer(
address vault,
uint256 oldBalance,
uint256 newBalance
) external onlyTrapConfig {
// NOTE: This is a simplified example of a response but can be extended to real world use cases.
// Mark the vault as handled
balanceDropHandled[vault] = true;
emit BalanceDropHandled(vault, oldBalance, newBalance, block.timestamp);

// Trigger emergency transfer to owner
try ISecuredVault(vault).emergencyTransferToOwner() {
emit EmergencyTransferTriggered(vault);
} catch {
// Vault doesn't support emergency transfer or transfer failed
}
}

// View function for testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,8 @@ contract SuddenBalanceDropTrap is ITrap {
// Monitor real treasury/vault addresses with major stablecoins
monitoredVaults.push(
VaultInfo({
vault: 0x742d35cC6634C0532925a3B8d80a6B24C5D06e41, // Example treasury
token: 0xa0B86a33e6441fD9Eec086d4E61ef0b5D31a5e7D // USDC
})
);

monitoredVaults.push(
VaultInfo({
vault: 0x8Ba1f109551Bd432803012645Aac136C40872A5F, // Example vault
token: 0xdAC17F958D2ee523a2206206994597C13D831ec7 // USDT
})
);

monitoredVaults.push(
VaultInfo({
vault: 0x742d35cC6634C0532925a3B8d80a6B24C5D06e41, // Example treasury
token: 0x6B175474E89094C44Da98b954EedeAC495271d0F // DAI
vault: 0x742d35cC6634C0532925a3B8d80a6B24C5D06e41,
token: 0xa0B86a33e6441fD9Eec086d4E61ef0b5D31a5e7D
})
);
}
Expand Down
Loading