The balanceDeployed() function in the strategy contracts calculates total deployed assets by summing the transmuter.getUnexchangedBalance(), the underlying token balance, and the asset token balance. However, it omits values that have already been converted (i.e., exchanged or claimable balances) and not reflected as unexchanged. As a result, the function underreports the total amount of deployed assets.
This calculation does not include assets that are no longer in the unexchanged state but may still be claimable or have been exchanged by the transmuter. Essentially, the function fails to fully account for all the assets that the strategy could realize and thus misrepresents the true value of the deployed funds.
When the strategy relies on balanceDeployed() for decision-making—such as determining when to harvest, withdraw, or report profits—the underestimation of deployed assets can lead to suboptimal operations. For example, the system may delay harvesting, incorrectly assess risk exposure, or misallocate resources because it does not have an accurate view of the total capital at its disposal.
pragma solidity ^0.8.18;
import "forge-std/console.sol";
import {Setup, ERC20, IStrategyInterface} from "./utils/Setup.sol";
import {IStrategyInterfaceVelo} from "../interfaces/IStrategyInterface.sol";
import {IStrategyInterfaceRamses} from "../interfaces/IStrategyInterface.sol";
import {IVeloRouter} from "../interfaces/IVelo.sol";
import {IRamsesRouter} from "../interfaces/IRamses.sol";
interface Strategy is IStrategyInterface {
function balanceDeployed() external returns (uint256);
}
contract PocTest is Setup {
function setUp() public virtual override {
super.setUp();
}
function test_poc_balanceDeployed() public {
uint256 test_amount = 10e18;
mintAndDepositIntoStrategy(strategy, user, test_amount);
console.log("Before Exchange Strategy(address(strategy)).balanceDeployed(): ", Strategy(address(strategy)).balanceDeployed());
console.log("Before Exchange Unexchanged Balance:", transmuter.getUnexchangedBalance(address(strategy)));
console.log("Before Exchange Exchangable Balance:", transmuter.getExchangedBalance(address(strategy)));
assertEq(Strategy(address(strategy)).balanceDeployed(), test_amount);
keeperExchange(test_amount);
console.log("After Exchange Strategy(address(strategy)).balanceDeployed(): ", Strategy(address(strategy)).balanceDeployed());
console.log("After Exchange Unexchanged Balance:", transmuter.getUnexchangedBalance(address(strategy)));
console.log("After Exchange Exchangable Balance:", transmuter.getExchangedBalance(address(strategy)));
assertLe(Strategy(address(strategy)).balanceDeployed(), test_amount);
}
function keeperExchange(uint256 _amount) public {
vm.roll(1);
deployMockYieldToken();
addMockYieldToken();
depositToAlchemist(_amount);
airdropToMockYield(_amount / 2);
vm.prank(whale);
asset.transfer(user2, _amount);
vm.prank(user2);
asset.approve(address(transmuter), _amount);
vm.prank(user2);
transmuter.deposit(_amount /2 , user2);
vm.roll(1);
harvestMockYield();
vm.prank(address(transmuterKeeper));
transmuterBuffer.exchange(address(underlying));
skip(7 days);
vm.roll(5);
vm.prank(user2);
transmuter.deposit(_amount /2 , user2);
vm.prank(address(transmuterKeeper));
transmuterBuffer.exchange(address(underlying));
}
}
Ran 1 test for src/test/testpoc.t.sol:PocTest
[PASS] test_poc_balanceDeployed() (gas: 3505736)
Logs:
Before Exchange Strategy(address(strategy)).balanceDeployed(): 10000000000000000000
Before Exchange Unexchanged Balance: 10000000000000000000
Before Exchange Exchangable Balance: 0
After Exchange Strategy(address(strategy)).balanceDeployed(): 9909899439067937440
After Exchange Unexchanged Balance: 9909899439067937440
After Exchange Exchangable Balance: 90100560932062560
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 19.31s (15.29s CPU time)
Ran 1 test suite in 20.27s (19.31s CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)
Update balanceDeployed() to include all relevant balances from the transmuter, such as transmuter.getClaimableBalance(address(this)) or any other applicable converted/exchanged assets. Accurately reflecting the total accessible asset pool ensures the strategy can make more informed and effective decisions.