This repository has been archived by the owner on Sep 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LinearRangeCurve.sol
110 lines (90 loc) · 3.78 KB
/
LinearRangeCurve.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {FixedPointMathLib} from '@solady/utils/FixedPointMathLib.sol';
import {ICurve} from '@flayer-interfaces/lssvm2/ICurve.sol';
import {CurveErrorCodes} from '@flayer-interfaces/lssvm2/CurveErrorCodes.sol';
/**
* Bonding curve logic for a linear curve where a buy/sell have no impact, but the price will
* just continue to decline on a range until it reaches zero.
*
* This curve is used for asset liquidation, where support for price fluctuations is less
* important than maintaining a liquidation schedule.
*/
contract LinearRangeCurve is ICurve, CurveErrorCodes {
using FixedPointMathLib for uint;
/**
* For a linear curve, all values of delta are valid.
*/
function validateDelta(uint128) external pure override returns (bool) {
return true;
}
/**
* For a linear curve, all values of spot price are valid.
*/
function validateSpotPrice(uint128) external pure override returns (bool) {
return true;
}
/**
* @dev See {ICurve-getBuyInfo}
*/
function getBuyInfo(uint128 spotPrice, uint128 delta, uint numItems, uint feeMultiplier, uint protocolFeeMultiplier) external view override returns (
Error error, uint128 newSpotPrice, uint128 newDelta, uint inputValue, uint tradeFee, uint protocolFee
) {
// We only calculate changes for buying 1 or more NFTs
if (numItems == 0) {
return (Error.INVALID_NUMITEMS, 0, 0, 0, 0, 0);
}
// Extract required variables from the delta
(uint32 start, uint32 end) = unpackDelta(delta);
// If the curve has not yet started, then we cannot process
if (block.timestamp < start) {
return (Error.INVALID_NUMITEMS, 0, 0, 0, 0, 0);
}
// If the curve has finished, then it's free
if (block.timestamp > end) {
return (Error.OK, 0, delta, 0, 0, 0);
}
// Determine the input value required to purchase the requested number of items
inputValue = numItems * (spotPrice * (end - block.timestamp) / (end - start));
// Account for the protocol fee, a flat percentage of the buy amount
protocolFee = inputValue.mulWadUp(protocolFeeMultiplier);
// Account for the trade fee, only for Trade pools
tradeFee = inputValue.mulWadUp(feeMultiplier);
// Add the protocol and trade fees to the required input amount
inputValue += tradeFee + protocolFee;
// Keep spot price and delta the same
newSpotPrice = spotPrice;
newDelta = delta;
// If we got all the way here, no math error happened
error = Error.OK;
}
/**
* We don't allow sells. Go away.
*/
function getSellInfo(uint128, uint128, uint, uint, uint) external pure override returns (Error error_, uint128, uint128, uint, uint, uint) {
return (Error.INVALID_NUMITEMS, 0, 0, 0, 0, 0);
}
/**
* Helper function that allows a delta to be generated in the expected format.
*
* @param start The unix timestamp that the curve starts
* @param end The unix timestamp that the curve ends
*
* @return The packed delta value
*/
function packDelta(uint32 start, uint32 end) public pure returns (uint128) {
return uint128(start) << 96 | uint128(end) << 64;
}
/**
* Helper function that allows a delta to be generated in the expected format.
*
* @param delta The delta to be unpacked
*
* @return start_ The unix timestamp that the curve starts
* @return end_ The unix timestamp that the curve ends
*/
function unpackDelta(uint128 delta) public pure returns (uint32 start_, uint32 end_) {
start_ = uint32(delta >> 96);
end_ = uint32((delta >> 64) & 0xFFFFFFFF);
}
}