Skip to content

Instantly share code, notes, and snippets.

@knek-little-projects
Created July 13, 2023 17:35
Show Gist options
  • Save knek-little-projects/10d9ff262d281212852a31c627eb7ece to your computer and use it in GitHub Desktop.
Save knek-little-projects/10d9ff262d281212852a31c627eb7ece to your computer and use it in GitHub Desktop.
@payable
@external
@nonreentrant('lock')
def create_loan(collateral: uint256, debt: uint256, N: uint256):
assert self.loan[msg.sender].initial_debt == 0, "Loan already created"
assert N > MIN_TICKS-1, "Need more ticks"
assert N < MAX_TICKS+1, "Need less ticks"
n1: int256 = self._calculate_debt_n1(collateral, debt, N)
n2: int256 = n1 + convert(N - 1, int256)
rate_mul: uint256 = self._rate_mul_w()
self.loan[msg.sender] = Loan({initial_debt: debt, rate_mul: rate_mul})
liquidation_discount: uint256 = self.liquidation_discount
self.liquidation_discounts[msg.sender] = liquidation_discount
n_loans: uint256 = self.n_loans
self.loans[n_loans] = msg.sender
self.loan_ix[msg.sender] = n_loans
self.n_loans = unsafe_add(n_loans, 1)
self._total_debt.initial_debt = self._total_debt.initial_debt * rate_mul / self._total_debt.rate_mul + debt
self._total_debt.rate_mul = rate_mul
# Start of the _deposit_range function
user_shares: DynArray[uint256, MAX_TICKS_UINT] = []
collateral_shares: DynArray[uint256, MAX_TICKS_UINT] = []
n0: int256 = self.active_band
assert n2 < 2**127
assert n1 > -2**127
lm: LMGauge = self.liquidity_mining_callback
for i in range(MAX_SKIP_TICKS + 1):
if n1 > n0:
if i != 0:
self.active_band = n0
break
assert self.bands_x[n0] == 0 and i < MAX_SKIP_TICKS, "Deposit below current band"
n0 -= 1
n_bands: uint256 = unsafe_add(convert(unsafe_sub(n2, n1), uint256), 1)
assert n_bands <= MAX_TICKS_UINT
y_per_band: uint256 = unsafe_div(collateral * COLLATERAL_PRECISION, n_bands)
assert y_per_band > 100, "Amount too low"
assert self.user_shares[msg.sender].ticks[0] == 0
self.user_shares[msg.sender].ns = unsafe_add(n1, unsafe_mul(n2, 2**128))
for i in range(MAX_TICKS):
band: int256 = unsafe_add(n1, i)
if band > n2:
break
assert self.bands_x[band] == 0, "Band not empty"
y: uint256 = y_per_band
if i == 0:
y = collateral * COLLATERAL_PRECISION - y * unsafe_sub(n_bands, 1)
total_y: uint256 = self.bands_y[band]
s: uint256 = self.total_shares[band]
ds: uint256 = unsafe_div((s + DEAD_SHARES) * y, total_y + 1)
assert ds > 0, "Amount too low"
user_shares.append(ds)
s += ds
assert s <= 2**128 - 1
self.total_shares[band] = s
total_y += y
self.bands_y[band] = total_y
if lm.address != empty(address):
collateral_shares.append(unsafe_div(total_y * 10**18, s))
self.min_band = min(self.min_band, n1)
self.max_band = max(self.max_band, n2)
self.save_user_shares(msg.sender, user_shares)
self.rate_mul = self._rate_mul()
self.rate_time = block.timestamp
if lm.address != empty(address):
lm.callback_collateral_shares(n1, collateral_shares)
lm.callback_user_shares(msg.sender, n1, user_shares)
# End of the _deposit_range function
self.minted += debt
self._deposit_collateral(collateral, msg.value)
STABLECOIN.transfer(msg.sender, debt)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment