Borrow shares and fees
How debt is recorded as shares, which way each conversion rounds, and the two fees on every borrow.
Supply has no shares — a market's supply is simply the Earn vault's claim, 1:1 in USDG
(LendingPoolRouter). Debt does: each borrower holds borrow
shares, and interest raises what every share is worth. The narrative is on
how it works.
Minting shares on a borrow
Where:
- — the amount borrowed, USDG base units.
- , —
totalBorrowAssetsandtotalBorrowSharesafter accrual.
Source: LendingPoolRouter. There are no virtual shares on the
borrow side. Rounding down favours the borrower: their recorded debt can start up to one share's
worth ( base units) below , and that gap is carried by everyone else's
shares. A borrow so small it would mint zero shares reverts.
Debt behind shares
This is what health checks value (IsHealthy · 0x9259…F9a1) and what a repayment of
shares pulls (LendingPoolRouter) — rounded down, in the repayer's
favour. A request for more shares than you hold is capped at your balance
(LendingPoolRouter), so type(uint256).max repays everything and
cannot be made to revert by someone repaying a share first; InsufficientShares fires only when you
hold none.
Liquidation and bad debt round the other way, in the lenders' favour:
Source: LendingPoolRouter, LendingPoolRouter.
Fees
Every borrow pays two fees, taken out of what the borrower receives. The debt booked is the full amount.
Where:
- — the protocol fee,
getProtocolFee(borrowToken). It is set per borrow token, not per market, and a stored 0 means 0.1% (1e15). - — the creator fee,
creatorFee(router), per market. A stored 0 means 0.01% (1e14). Live on every market: 1 (1e-18), which is off.
Source: LendingPoolRouter, LendingPoolRouter,
LendingPoolFactory · 0x7a2b…b1C6; paid out in LendingPool.
Each fee is capped at MAX_BORROW_FEE = 10% (1e17) when set
(LendingPoolFactory · 0x7a2b…b1C6, LendingPoolFactory · 0x7a2b…b1C6).
And because a stored 0 restores the default, neither fee can be set to zero. To switch the
creator fee off, the owner sets it to 1 instead (factory.setCreatorFee(router, 1)): 1 wei-WAD of
any borrow under 10¹⁸ base units — a trillion USDG — floors to 0. The protocol fee goes to the
factory's protocol() address, the creator fee to the market's creator. protocol() is a 2-of-4
Safe. The protocol fee is at its 0.1% default and the creator fee is 1 (off) on all three launch
markets (read at block 86868761, and again at block 92690105), on all five at block 94915008, on
MSFT/USDG and AAPL/USDG at block 99393260, and on QQQ/USDG, GOOGL/USDG and AMD/USDG at block
113204091.
Worked example: borrowing 1,000 USDG
In the illustrative market, before accrual:
20010000000, 20000000000.
Shares:
After the borrow, 21010000000 and 20999500249. Those 999,500,249
shares are worth 999999999 (999.999999 USDG) rounded down and 1000000000 (1,000.000000 USDG)
rounded up — the borrower's recorded debt starts one base unit below what they borrowed.
Fees:
| Raw | USDG | |
|---|---|---|
| Borrowed, debt booked | 1000000000 | 1,000.000000 |
| Protocol fee (0.1%) | 1000000 | 1.000000 |
| Creator fee (, off) | 0 | 0.000000 |
| Received | 999000000 | 999.000000 |
So the borrower walks away with 999.00 USDG and owes 1,000 — an effective upfront cost of 0.10%
before any interest. Health and LTV are checked against the full 1,000 of debt, not the 999.00
received. (At the creator fee's 0.01% default, a stored 0, would be 100000 and the
borrower would receive 998.90.)
(In practice the borrow accrues first, so would include the pending 9.117741 USDG of interest from accrual and the share count would be slightly lower. The arithmetic is the same.)