Transparency Report: A Brokerbot Smart Contract Vulnerability and Its Remediation

Aktionariat Team Published on

On 23 April 2026, an attacker was able to find and exploit a bug in one of Aktionariat's smart contracts — the Brokerbot contract — that, under certain preconditions, made it possible to effectively drain the stablecoin reserve of a Brokerbot.

Four issuers with Brokerbot contract configurations matching those preconditions were affected. A total of CHF 31'606 in the form of Frankencoin (ZCHF) was stolen by the attacker.

Aktionariat reimbursed all losses incurred by the four affected issuers. The bug was patched and new PaymentHub and Brokerbot contracts were rolled out to all issuers. The configuration that enabled the attack was also disabled for all issuers.

Although the malicious transactions involved interacting with the primary market to buy and sell back the issuers' tokenized shares, no shares were stolen. Ownership and shareholder registry records therefore remain fully intact.

No investors or shareholders were affected.

Facts

Exploit date 23.04.2026
Issuers impacted 4
Amount stolen CHF 31'606
Status Resolved. Issuers fully reimbursed and the bug has been patched.

What Happened

The bug was caused by a faulty calculation in one of Aktionariat's smart contracts that, under specific circumstances and with specially constructed transactions, let the buyer receive one more share than they should have received based on the price paid. This was only possible in configurations with a positive price increment, where the share price increases monotonically with every purchase.

To reach these conditions, an attacker had to find companies where:

  • buybacks in the primary market were enabled,
  • a non-zero price increment was set, and
  • there was at least some ZCHF balance on the Brokerbot contract.

The attacker then exploited the bug by looping over the same faulty calculation multiple times in a single transaction. In each iteration, the attacker:

  • bought shares with a very specific amount, thereby receiving one more share than paid for; and
  • sold all shares back, including the extra one, thereby netting the price of one share in ZCHF.

The loop continued until the entire ZCHF reserve of the Brokerbot contract was drained. At the end of the transaction, the stolen ZCHF was immediately converted to ETH and transferred away. MEV bots were used to obfuscate the attacker and to avoid public transaction pools.

Upon discovery of the bug, Aktionariat, in parallel:

  • identified the root cause, the preconditions, and which issuers were or could be affected;
  • calculated the impact and decided that all losses would be covered by Aktionariat;
  • started implementing and rolling out a patch and a configuration that removes the bug and makes the faulty configuration impossible; and
  • started planning direct communication to affected clients.

Technical Root Cause

The erroneous calculation is in getShares, a function that calculates the number of shares to be received for a given ZCHF amount:

function getShares(uint256 money) public view returns (uint256) {
    uint256 currentPrice = getPrice();
    uint256 min = 0;
    uint256 max = money / currentPrice;
    while (min < max){
        uint256 middle = (min + max)/2;
        uint256 totalPrice = getPrice(currentPrice, middle);
        if (money > totalPrice){
            min = middle + 1;
        } else {
            max = middle;
        }
    }
    return min;
}

The problematic parts are highlighted above. Most importantly, if the given money is above the calculated totalPrice, the loop exits with min = middle + 1, even though the extra payment could be far less than the price of a full share. Note that this path is only used when a price increment is set.

The PaymentHub contract triggering the trade was also not checking the returned result — for example by simply enforcing that getBuyPrice(share amount) < total paid — which would have prevented exploitation of the faulty calculation.

Remedy

  • Aktionariat detected the amounts stolen from the Brokerbot contracts and fully reimbursed the affected issuers. As a result, no issuer lost money.
  • An upgraded Brokerbot contract was developed and deployed that fixes the calculation bug.
  • An upgraded PaymentHub contract was developed, deployed, and rolled out to issuers through multisig proposals. The new PaymentHub contract checks the sanity of payments and blocks off-by-one errors.
  • Buybacks were disabled for the Brokerbots at risk. Note that, without the PaymentHub update, disabling buybacks alone would still allow an attacker to obtain one more share than intended. However, on-chain attackers are mostly not interested in stealing shares or holding tokens; they only execute transactions whose proceeds can be liquidated immediately, so disabling buybacks effectively blocks the attacker.
  • New Direct Investment contracts from Aktionariat do not have the buyback feature, so the entire problematic (but now fixed) block is already irrelevant and has been removed.

Lessons Learned

The biggest surprise and lesson for us was to find a bug with critical impact in contracts that have passed security checks and formal audits multiple times. This bug had been in place for at least five years and somehow escaped the scrutiny of all of our smart contract developers, both technical co-founders, and two paid audits. That unfortunately makes us question the value of the audits we received from our auditors.

The fact that the bug lay dormant for five years and resurfaced only now hints at attackers using AI-assisted tools that make wider, automated exploit searches viable. A significant uptick in exploits across the crypto scene in general has been observed, which necessitates tighter security practices and the use of AI for defence and continuous auditing.

Acknowledgements

We take full responsibility for this incident and sincerely apologize to all affected issuers. We can only be relieved by the fact that we were able to make all issuers whole, analyse and contain the damage, update the impacted contracts as quickly as possible, and mark this incident as resolved without our issuers or investors incurring any losses.

Full List of Malicious Transactions

The complete list of malicious transactions is provided below for full transparency. Each entry links to the transaction on Etherscan.

Interested in more?

Start today for free or let us show you how it works.