@@ -124,55 +124,64 @@ contract Liquidation is BaseLogic {
124
124
OverrideConfig memory overrideConfig;
125
125
AssetConfig memory collateralConfig;
126
126
AssetConfig memory underlyingConfig;
127
- if (liqLocs.underlying == liqLocs.collateral) {
128
- liqOpp.repay = type (uint ).max;
129
- } else {
130
- collateralConfig = resolveAssetConfig (liqLocs.collateral);
131
- underlyingConfig = resolveAssetConfig (liqLocs.underlying);
132
-
133
- uint collateralFactor = collateralConfig.collateralFactor;
134
- uint borrowFactor = underlyingConfig.borrowFactor;
135
-
136
- if (liqLocs.overrideCollateralValue > 0 ) {
137
- overrideConfig = overrideLookup[liqLocs.underlying][liqLocs.collateral];
138
- }
139
127
140
- // If override is active, assume the resulting liability will be fully covered by override collateral
141
- if (overrideConfig.enabled) { // the liquidated collateral is an override
142
- collateralFactor = overrideConfig.collateralFactor;
143
- borrowFactor = CONFIG_FACTOR_SCALE ;
128
+ collateralConfig = resolveAssetConfig (liqLocs. collateral);
129
+ underlyingConfig = liqLocs.underlying == liqLocs. collateral
130
+ ? collateralConfig
131
+ : resolveAssetConfig (liqLocs.underlying) ;
144
132
133
+ uint collateralFactor = collateralConfig.collateralFactor;
134
+ uint borrowFactor = underlyingConfig.borrowFactor;
135
+
136
+ // If override is active for the liquidated pair, assume the resulting liability will be fully covered by override collateral, and adjust inputs
137
+ if (liqLocs.overrideCollateralValue > 0 ) {
138
+ if (liqLocs.underlying == liqLocs.collateral) { // liquidating self-collateral
139
+ collateralFactor = SELF_COLLATERAL_FACTOR;
140
+ borrowFactor = CONFIG_FACTOR_SCALE;
145
141
// adjust the whole liability for override BF = 1
146
142
liqLocs.liabilityValue = liqLocs.currentOwed * liqLocs.underlyingPrice / 1e18 ;
147
- }
143
+ } else {
144
+ overrideConfig = overrideLookup[liqLocs.underlying][liqLocs.collateral];
148
145
149
- // Calculate for no overrides or resulting liability fully covered by override
150
- // or if liquidating non-override collateral assume result will be partially covered by override
151
- calculateRepayCommon (liqOpp, liqLocs, collateralFactor, borrowFactor);
146
+ if (overrideConfig.enabled) { // the liquidated collateral has active override with liability
147
+ collateralFactor = overrideConfig.collateralFactor;
148
+ borrowFactor = CONFIG_FACTOR_SCALE;
149
+ // adjust the whole liability for override BF = 1
150
+ liqLocs.liabilityValue = liqLocs.currentOwed * liqLocs.underlyingPrice / 1e18 ;
151
+ }
152
+ }
152
153
}
153
154
155
+ // Calculate for no overrides or resulting liability fully covered by override
156
+ // or if liquidating non-override collateral assume result will be partially covered by override
157
+ calculateRepayCommon (liqOpp, liqLocs, collateralFactor, borrowFactor);
158
+
154
159
// Limit repay and yield to current debt and available collateral
155
160
boundRepayAndYield (liqOpp, liqLocs);
156
161
157
162
// Test the assumptions and adjust if needed
158
163
159
164
// Correction when liquidating override collateral
160
165
if (
161
- // Override and regular collateral, liquidating collateral
162
- overrideConfig.enabled && liqLocs.overrideCollateralValue != liqLocs.collateralValue &&
166
+ // override and regular collateral present
167
+ liqLocs.overrideCollateralValue != liqLocs.collateralValue &&
168
+ // liquidating collateral with override or self-collateral
169
+ (overrideConfig.enabled || liqLocs.underlying == liqLocs.collateral) &&
163
170
// not already maxed out
164
171
liqOpp.yield != liqLocs.collateralBalance &&
165
172
// result is not fully covered by override collateral as expected
166
173
(liqOpp.repay == 0 || // numerator in equation was negative
167
174
(liqLocs.currentOwed - liqOpp.repay) * liqLocs.underlyingPrice / 1e18 >
168
- liqLocs.overrideCollateralValue - liqOpp.yield * overrideConfig. collateralFactor / CONFIG_FACTOR_SCALE * liqLocs.collateralPrice / 1e18 )
175
+ liqLocs.overrideCollateralValue - liqOpp.yield * collateralFactor / CONFIG_FACTOR_SCALE * liqLocs.collateralPrice / 1e18 )
169
176
) {
170
- uint auxAdj = 1e18 * CONFIG_FACTOR_SCALE / underlyingConfig.borrowFactor - 1e18 ;
171
- uint borrowAdj = underlyingConfig.borrowFactor != 0 ? TARGET_HEALTH * CONFIG_FACTOR_SCALE / underlyingConfig.borrowFactor : MAX_SANE_DEBT_AMOUNT;
172
- uint collateralAdj = 1e18 * uint (overrideConfig.collateralFactor) / CONFIG_FACTOR_SCALE * (TARGET_HEALTH * auxAdj / 1e18 + 1e18 ) / (1e18 - liqOpp.discount);
177
+ borrowFactor = underlyingConfig.borrowFactor;
178
+
179
+ uint auxAdj = 1e18 * CONFIG_FACTOR_SCALE / borrowFactor - 1e18 ;
180
+ uint borrowAdj = borrowFactor != 0 ? TARGET_HEALTH * CONFIG_FACTOR_SCALE / borrowFactor : MAX_SANE_DEBT_AMOUNT;
181
+ uint collateralAdj = 1e18 * collateralFactor / CONFIG_FACTOR_SCALE * (TARGET_HEALTH * auxAdj / 1e18 + 1e18 ) / (1e18 - liqOpp.discount);
173
182
174
183
uint overrideCollateralValueAdj = liqLocs.overrideCollateralValue * auxAdj / 1e18 ;
175
- uint liabilityValueAdj = liqLocs.currentOwed * liqLocs.underlyingPrice / 1e18 * CONFIG_FACTOR_SCALE / underlyingConfig. borrowFactor;
184
+ uint liabilityValueAdj = liqLocs.currentOwed * liqLocs.underlyingPrice / 1e18 * CONFIG_FACTOR_SCALE / borrowFactor;
176
185
177
186
if (liabilityValueAdj < overrideCollateralValueAdj || borrowAdj <= collateralAdj) {
178
187
liqOpp.repay = type (uint ).max;
@@ -190,16 +199,20 @@ contract Liquidation is BaseLogic {
190
199
191
200
// Correction when liquidating regular collateral with overrides present
192
201
if (
193
- // liquidating regular collateral, override present
194
- ! overrideConfig.enabled && liqLocs.overrideCollateralValue > 0 &&
202
+ // liquidating regular collateral
203
+ ! (overrideConfig.enabled || liqLocs.underlying == liqLocs.collateral) &&
204
+ // override present
205
+ liqLocs.overrideCollateralValue > 0 &&
195
206
// not already maxed out
196
207
liqOpp.yield != liqLocs.collateralBalance &&
197
208
// result is not partially collateralised as expected
198
209
(liqLocs.currentOwed - liqOpp.repay) * liqLocs.underlyingPrice / 1e18 < liqLocs.overrideCollateralValue
199
210
) {
200
211
// adjust the whole liability for override BF = 1
201
212
liqLocs.liabilityValue = liqLocs.currentOwed * liqLocs.underlyingPrice / 1e18 ;
202
- calculateRepayCommon (liqOpp, liqLocs, collateralConfig.collateralFactor, CONFIG_FACTOR_SCALE);
213
+
214
+ collateralFactor = collateralConfig.collateralFactor;
215
+ calculateRepayCommon (liqOpp, liqLocs, collateralFactor, CONFIG_FACTOR_SCALE);
203
216
204
217
liqOpp.repay = liqOpp.repay == 0 ? type (uint ).max : liqOpp.repay;
205
218
@@ -218,7 +231,7 @@ contract Liquidation is BaseLogic {
218
231
uint collateralAdj = 1e18 * collateralFactor / CONFIG_FACTOR_SCALE * 1e18 / (1e18 - liqOpp.discount);
219
232
uint liabilityValue = liqLocs.liabilityValue * TARGET_HEALTH / 1e18 ;
220
233
221
- if (liabilityValue > liqLocs.collateralValue) { // TODO L < 0
234
+ if (liabilityValue > liqLocs.collateralValue) {
222
235
if (borrowAdj <= collateralAdj) {
223
236
liqOpp.repay = type (uint ).max;
224
237
} else {
0 commit comments