Hi Oleg, thanks for the reply.
- TOKEN-TO-COTA CONVERSION
You’re right, and our proposal language was wrong. Let me give the design
rationale first, because the naming error obscured a deliberate choice.
There are two ways to tokenize a yielding fund position. A distributing
token, where price stays at par and yield arrives as new tokens. Or a
value-accruing token, where supply is fixed and NAV per token rises. We
chose accrual, for three reasons.
First, distribution breaks collateral. Yield delivered as new tokens would
have to reach every holder, including your escrow vault and any contract
holding the token. In the escrow, newly minted tokens would not be credited
to the borrower’s position, so the yield would strand in the vault and the
oracle would report par indefinitely. The borrower’s LTV would never
improve.
Second, accrual makes the collateral self-improving, which we believe is
credit-positive for you. At current rates our collateral accrues at 13.93%
while the debt accrues at 4.56%, so LTV falls 8.22% per year with no
transaction:
year LTV FX distance to liquidation
0 33.5% +130%
1 30.8% +150%
3 25.9% +197%
5 21.8% +253%
That property exists only because NAV accrues.
Third, operational. Monthly yield distribution to every holder is a
recurring uncapped mint, which is the class of privileged operation we are
removing from the system, not adding to it.
On normalization: we set NAV per token to 1.000000 BRL at inception rather
than to one cota. The unit would be awkward at 5.59 BRL, but the
substantive reason is decoupling. A BRL-denominated unit does not break if
the underlying DI fund or the custodian changes.
The design conversion is:
navPerToken(t) = VL_QUOTA(t) / VL_QUOTA(t0)
with t0 = 2026-05-20 and VL_QUOTA(t0) = 5.450605982603, the CVM-filed
quota for that date (inf_diario_fi_202605, CNPJ 09.215.250/0001-13).
Two precisions on that, because you will recompute it. First, the 5.4346
you derived is a date-pairing artifact, not our constant: it divides the
2026-07-22 quota (5.577413235374) by a NAV printed two business days
later. Pairing quota and NAV on the same reference date gives a stable
ratio: the latest filed quota, 2026-07-28 at 5.589039480495, against NAV
deflated to that print date (1.026802) gives 5.4432. Second, that 5.4432
differs from the inception constant by about 14 bps, and we would rather
state why than have you find it: between inception and the introduction
of the print-anchored oracle, daily NAV between official quota
publications was interpolated on realized CDI, and that interpolation ran
slightly ahead of the fund’s print ratio. When the print-anchored oracle
went live it adopted the prevailing level without a step change — a level
jump would have repriced existing holders — and from its anchor forward
the ratio to the official prints is enforced. The basis is a fixed
historical offset, not a growing one.
We will publish the inception date, the inception quota, and the anchored
conversion in the contract documentation, and correct the proposal to read
“backed by fund cotas, denominated in BRL at inception NAV” rather than
“1:1 by cotas.” The audit report and the contract NatSpec both already
describe BRL denomination. The cota language was an error in the proposal
document, not in the deployed system.
- AUDIT SCOPE
EfixDITokenBase is not covered. The OpenZeppelin engagement scoped one
repository at one commit and one file, contracts/EfixDIToken.sol, and the
audited deployment was the Polygon contract at
0x04082b283818D9d0dd9Ee8742892eEe5CC396441. The report’s conclusion states
the engagement was limited to that contract and that integrations,
including the collateral vault, were not reviewed.
The delta between the audited contract and the deployed one:
removed: BURNER_ROLE, adjustable max supply, treasury address,
emergencyWithdraw, global transfer pause
added: bridge mint/burn, pause scoped to bridgeIn/bridgeOut only
On the bridge functions, which are the bulk of that delta: the LayerZero
bridge was permanently discontinued in May 2026. The trigger was not the
audit. A separate on-chain security review found that the MinterBurner
contract had been deployed by a key we had reason to treat as compromised,
and that the token’s DEFAULT_ADMIN_ROLE sat on an exposed EOA. Rather than
redeploy the bridge under a new key, we discontinued it entirely, cut over
to a Base-native mint pipeline, and moved token roles to a Safe multisig.
Roughly R$ 1,156 of retail balance remains stranded on Polygon as a
consequence, which we accepted.
Verifiable now on 0xF5cA55f3ea5Bcd180aEa6dF9E05a0E63A66f5608 via hasRole:
DEFAULT_ADMIN_ROLE / 0x9eFc11e4d285b5a749faFBC2613836Dcda899e12 false
BRIDGE_ROLE / 0x9eFc11e4d285b5a749faFBC2613836Dcda899e12 false
MINTER_ROLE / 0x9eFc11e4d285b5a749faFBC2613836Dcda899e12 false
PAUSER_ROLE / 0x9eFc11e4d285b5a749faFBC2613836Dcda899e12 false
BRIDGE_ROLE / 0x400a8DE2bF8fc4A63000A7E77103eDAE897CB9a3 false
MINTER_ROLE / 0x400a8DE2bF8fc4A63000A7E77103eDAE897CB9a3 false
DEFAULT_ADMIN_ROLE / 0x7C54Dccd6fC5DB73b34f32aCA4d1631E054c7537 false
0x9eFc is the previously exposed operator EOA, 0x400a is the MinterBurner,
0x7C54 is the compromised deployer.
One caveat worth stating: the contract inherits plain AccessControl, not
AccessControlEnumerable, so role membership cannot be enumerated by view
call. The statement above is that these specific addresses hold no roles,
not that the role sets are provably empty. DEFAULT_ADMIN_ROLE is held by
our Safe multisig at 0x9040b4E9e1F8C96dC6dEF1a2d6f4105D8535EeD4. The full
RoleGranted and RoleRevoked history from the Base deployment block is
available on request.
Separately, the March audit did produce a high-severity finding, H-01, on
collateral burn accounting: a user could transfer efixDI out while the
vault still tracked their position, which made burnFrom revert during
liquidation. We mitigated it with a custodial collateral vault where
withdrawal is blocked in Solidity while debt is outstanding, rather than by
patching the token.
- ON REMEDIATION
We are not going to promise an audit we have not scheduled. What we can do
is bound your exposure to something you verify independently.
We propose the borrow cap be a function of attested collateral rather than
a fixed number: 65% of the fund’s attested NAV, with the CVM informe
published monthly as the attestation. At today’s NAV that is approximately
US$ 1,985.
Absolute ceilings in tranches, each step conditioned on the previous
holding 60% utilization for 30 days:
US$ 25,000 → US$ 100,000 → uncapped
This bounds the exposure of unaudited code to a fraction of collateral you
can verify against a regulator-filed document, and removes the need to take
our word on scale.
Compensating controls currently in place, all verifiable on-chain: token
roles held by a Safe multisig rather than an EOA; collateral escrow vault
with governance renounced; a smaller privileged surface than the audited
contract, with no emergencyWithdraw, no adjustable max supply, no treasury
address and no global transfer pause; and D+0 redemption of the underlying
fund, so liquidation does not depend on a secondary market.
- INVESTOR-RELATIONS PAGE
We have corrected our investor-relations page, which placed the audit scope
adjacent to the Base contract address in a way that implied coverage it
does not have. The page now states the audited contract and chain
explicitly, lists what was not in scope, and carries a scope note covering
the delta and the bridge discontinuation. It is live:
https://efix.finance/public/efixdi/investor-relations/
Ernesto