Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: low
Likelihood: high

Missing Events for Critical Parameter Changes

Author Revealed upon completion

Root + Impact

Location: src/Stratax.sol:263-275

Description

setStrataxOracle() and setFlashLoanFee() modify two of the most security-critical protocol parameters — the price source used for all leverage calculations and the fee applied to every flash loan. Neither function emits an event.

// src/Stratax.sol:263-266
function setStrataxOracle(address _strataxOracle) external onlyOwner {
require(_strataxOracle != address(0), "Invalid oracle address");
strataxOracle = _strataxOracle; // @> no event emitted
}
// src/Stratax.sol:272-275
function setFlashLoanFee(uint256 _flashLoanFeeBps) external onlyOwner {
require(_flashLoanFeeBps < FLASHLOAN_FEE_PREC, "Fee must be < 100%");
flashLoanFeeBps = _flashLoanFeeBps; // @> no event emitted
}

Risk

Likelihood:

  • These functions will be called in normal operations whenever the oracle is upgraded or the fee is adjusted

  • No event means no transaction log entry for off-chain systems to consume

Impact:

  • Off-chain monitors cannot detect oracle substitution — a compromised oracle swap goes undetected until positions are affected

  • Fee changes are invisible to users and indexers relying on event logs

  • Inconsistent with the OwnershipTransferred event already present in StrataxOracle

Proof of Concept

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Test} from "forge-std/Test.sol";
import {Stratax} from "../../src/Stratax.sol";
import {Vm} from "forge-std/Vm.sol";
contract MissingEventsPoCTest is Test {
Stratax stratax;
function test_setStrataxOracleEmitsNoEvent() public {
address newOracle = address(0xABC);
address owner = stratax.owner();
// Record all logs emitted during this call
vm.recordLogs();
vm.prank(owner);
stratax.setStrataxOracle(newOracle);
Vm.Log[] memory logs = vm.getRecordedLogs();
// No events emitted — off-chain monitors cannot detect oracle change
assertEq(logs.length, 0); // @> zero events for a critical state change
}
function test_setFlashLoanFeeEmitsNoEvent() public {
vm.recordLogs();
vm.prank(stratax.owner());
stratax.setFlashLoanFee(50);
Vm.Log[] memory logs = vm.getRecordedLogs();
assertEq(logs.length, 0); // @> fee change invisible to indexers
}
}

Recommended Mitigation

Declare and emit events for both functions, logging the previous and new values. This allows off-chain monitoring systems, subgraphs, and users to detect oracle or fee changes in real time and react before positions are opened with updated parameters.

+ event OracleUpdated(address indexed previousOracle, address indexed newOracle);
+ event FlashLoanFeeUpdated(uint256 previousFee, uint256 newFee);
function setStrataxOracle(address _strataxOracle) external onlyOwner {
require(_strataxOracle != address(0), "Invalid oracle address");
+ emit OracleUpdated(strataxOracle, _strataxOracle);
strataxOracle = _strataxOracle;
}
function setFlashLoanFee(uint256 _flashLoanFeeBps) external onlyOwner {
require(_flashLoanFeeBps < FLASHLOAN_FEE_PREC, "Fee must be < 100%");
+ emit FlashLoanFeeUpdated(flashLoanFeeBps, _flashLoanFeeBps);
flashLoanFeeBps = _flashLoanFeeBps;
}

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!