Sense Finance Access Control Issue Bugfix Review

Summary
On April 22, whitehat Violet Vienhage submitted a critical vulnerability in Sense Finance via Immunefi. Sense operates as decentralized, permissionless infrastructure, where teams can build and develop new yield primitives for DeFi, such as bond-like assets, yield tokens, and tranche-like instruments. Yield-stripping is the first application built on Sense, where users can lend at a fixed rate and make capital-efficient long/short bets on the future yields of existing yield-bearing assets. For more information about Sense Finance, please visit https://sense.finance/ and read Sense’s bugfix review here.
The vulnerability consisted of a missing access control issue in the onSwap()
function of the Sense Balancer pool that could have allowed a malicious actor to update the oracle data of the Space AMM contract. There were no assets at risk, as the pools relying on the Space AMM oracle were paused by the Sense team upon vulnerability disclosure. Sense has paid the full $50,000 bounty to the whitehat and has already deployed a fix to the mainnet.
Vulnerability Analysis
Sense Space is an AMM (Automated Market Maker) contract developed by Sense Finance, which is built on top of Balancer V2, implements the yieldspace invariant, and is the central market for Principal Tokens (PTs) & Yield Tokens (YTs) trading.
Balancer is an automated portfolio manager, liquidity provider, and price sensor. For more details on how Balancer works, check out Balancer’s blog post. When the Balancer vault handles a swap between the tokens, it will do a callback on the onSwap()
function on the Space AMM pool to determine the output amounts with all tokens balances. The callback also updates the stored oracle information on the pool contract, in addition to the reserve information provided by the Balancer vault.
The vulnerability that the whitehat identified was that the onSwap()
function on the Space AMM pool contract didn’t validate if the caller was the Balancer vault. Hence, a malicious actor could have directly called the onSwap()
function on the pool, provided any price/reserves information to the oracle, and then have the oracle set that into the state. The oracle would then read out as having that price recorded arbitrarily far into the past or future.
The pool contract has an onlyVault()
modifier which allows the calls from the balancer vault contract and was placed on the onJoin()
and onExit()
functions of the pool but did not have it on the onSwap()
functionality. Thus, anyone can call this onSwap()
with attacker-controlled request data to manipulate the stored oracle data.
Since the Sense Fuse pools at Rari Capital were relying on the Space AMM contract oracle, the vulnerability could have allowed a malicious actor to perform theft of any borrowable collateral provided to the Rari pools, and the theft of any assets of the users which have been borrowed against — liquidation of collateral, taking a bad loan, all by manipulating the oracle price and timestamp.
Vulnerability Fix
The Sense team fixed the vulnerability by adding a condition to update the oracle update of the pool only if the caller is the Balancer vault.
Acknowledgements
We would like to thank Violet Vienhage for doing an amazing job and responsibly disclosing such an important bug. Big props also to the Sense Finance team who responded quickly to the report and patched it.
If you’d like to start bug hunting, we got you. Check out the Web3 Security Library, and start earning rewards on Immunefi — the leading bug bounty platform for web3 with the world’s biggest payouts.
And if you’re feeling good about your skillset and want to see if you will find bugs in the code, check out the bug bounty program from Sense Finance.