Skip to content

Commit f04e70f

Browse files
yuchenlinttskalermovanruch
authored
Call LF2.createFTLALoanToken() from FTLA.fund() (trusttoken#962)
* Rename local lender variable to ftlAgency * Add FTLA setters + state to truefi2 contracts * Fix test * Copy validity checks from LF2.createLoanToken() to FTLA.fund() * Strip deprecated functions + state from FTLA (trusttoken#957) * Strip deprecated functionality from FTLA * Refactor imports * Fix lint * Remove obsolete comment * Remove distribute() function * Remove code related to TrueRatingAgency from FTLA tests * Call LF2.createFTLALoanToken() from FTLA.fund() * Fix test typecheck and lint; tests still broken... * increase apy in tests * Fix test values with auto apys * fix lint * wip * fix FTLA tests * fix lint * fix deploy typings Co-authored-by: Roman Moskalenko <34585360+skalermo@users.noreply.github.com> Co-authored-by: Ivan Rukhavets <ivanruch@gmail.com>
1 parent eec10b5 commit f04e70f

File tree

4 files changed

+137
-134
lines changed

4 files changed

+137
-134
lines changed

contracts/truefi2/FixedTermLoanAgency.sol

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {UpgradeableClaimable} from "../common/UpgradeableClaimable.sol";
1111
import {OneInchExchange} from "./libraries/OneInchExchange.sol";
1212

1313
import {ILoanToken2} from "./interface/ILoanToken2.sol";
14+
import {ILoanFactory2} from "./interface/ILoanFactory2.sol";
1415
import {IDebtToken} from "../truefi2/interface/ILoanToken2.sol";
1516
import {IStakingPool} from "../truefi/interface/IStakingPool.sol";
1617
import {IFixedTermLoanAgency} from "./interface/IFixedTermLoanAgency.sol";
@@ -63,7 +64,7 @@ contract FixedTermLoanAgency is IFixedTermLoanAgency, UpgradeableClaimable {
6364

6465
IStakingPool public stakingPool;
6566

66-
IPoolFactory public factory;
67+
IPoolFactory public poolFactory;
6768

6869
I1Inch3 public _1inch;
6970

@@ -89,6 +90,8 @@ contract FixedTermLoanAgency is IFixedTermLoanAgency, UpgradeableClaimable {
8990
// mutex ensuring there's only one running loan or credit line for borrower
9091
IBorrowingMutex public borrowingMutex;
9192

93+
ILoanFactory2 public loanFactory;
94+
9295
mapping(address => bool) public isBorrowerAllowed;
9396

9497
// ======= STORAGE DECLARATION END ============
@@ -162,7 +165,7 @@ contract FixedTermLoanAgency is IFixedTermLoanAgency, UpgradeableClaimable {
162165
* @dev Can be only called by a pool
163166
*/
164167
modifier onlySupportedPool() {
165-
require(factory.isSupportedPool(ITrueFiPool2(msg.sender)), "FixedTermLoanAgency: Pool not supported by the factory");
168+
require(poolFactory.isSupportedPool(ITrueFiPool2(msg.sender)), "FixedTermLoanAgency: Pool not supported by the factory");
166169
_;
167170
}
168171

@@ -174,25 +177,27 @@ contract FixedTermLoanAgency is IFixedTermLoanAgency, UpgradeableClaimable {
174177
/**
175178
* @dev Initialize the contract with parameters
176179
* @param _stakingPool stkTRU address
177-
* @param _factory PoolFactory address
180+
* @param _poolFactory PoolFactory address
178181
* @param __1inch 1Inch exchange address (0x11111112542d85b3ef69ae05771c2dccff4faa26 for mainnet)
179182
*/
180183
function initialize(
181184
IStakingPool _stakingPool,
182-
IPoolFactory _factory,
185+
IPoolFactory _poolFactory,
183186
I1Inch3 __1inch,
184187
ITrueFiCreditOracle _creditOracle,
185188
ITrueRateAdjuster _rateAdjuster,
186-
IBorrowingMutex _borrowingMutex
189+
IBorrowingMutex _borrowingMutex,
190+
ILoanFactory2 _loanFactory
187191
) public initializer {
188192
UpgradeableClaimable.initialize(msg.sender);
189193

190194
stakingPool = _stakingPool;
191-
factory = _factory;
195+
poolFactory = _poolFactory;
192196
_1inch = __1inch;
193197
creditOracle = _creditOracle;
194198
rateAdjuster = _rateAdjuster;
195199
borrowingMutex = _borrowingMutex;
200+
loanFactory = _loanFactory;
196201

197202
swapFeeSlippage = 100; // 1%
198203
fee = 1000;
@@ -302,55 +307,47 @@ contract FixedTermLoanAgency is IFixedTermLoanAgency, UpgradeableClaimable {
302307
address borrower,
303308
uint256 amount,
304309
uint256 term
305-
) internal view returns (uint256) {
310+
) public view returns (uint256) {
306311
uint8 borrowerScore = creditOracle.score(borrower);
307312
uint256 fixedTermLoanAdjustment = rateAdjuster.fixedTermLoanAdjustment(term);
308313
return rateAdjuster.rate(pool, borrowerScore, amount).add(fixedTermLoanAdjustment);
309314
}
310315

311316
/**
312-
* @dev Fund a loan
313-
* LoanToken should be created by the LoanFactory over the pool
314-
* than was also created by the PoolFactory.
317+
* @dev Create and fund a loan via LoanFactory for a pool supported by PoolFactory
315318
* Method should be called by the loan borrower
316319
*
317320
* When called, agency takes funds from the pool, gives it to the loan and holds all LoanTokens
318321
* Origination fee is transferred to the stake
319-
*
320-
* @param loanToken LoanToken to fund
321322
*/
322-
function fund(ILoanToken2 loanToken) external onlyAllowedBorrowers {
323-
// TODO Replace hardcoded _maxApy value with a param
324-
uint256 _maxApy = 10000;
325-
326-
ITrueFiPool2 pool = loanToken.pool();
327-
require(factory.isSupportedPool(pool), "FixedTermLoanAgency: Pool not supported by the factory");
328-
require(loanToken.token() == pool.token(), "FixedTermLoanAgency: Loan and pool token mismatch");
323+
function fund(
324+
ITrueFiPool2 pool,
325+
uint256 amount,
326+
uint256 term,
327+
uint256 _maxApy
328+
) external onlyAllowedBorrowers {
329+
require(poolFactory.isSupportedPool(pool), "FixedTermLoanAgency: Pool not supported by the factory");
329330
require(poolLoans[pool].length < maxLoans, "FixedTermLoanAgency: Loans number has reached the limit");
330331

331-
address borrower = loanToken.borrower();
332-
require(msg.sender == borrower, "FixedTermLoanAgency: Sender is not borrower");
332+
address borrower = msg.sender;
333333
require(borrowingMutex.isUnlocked(borrower), "FixedTermLoanAgency: There is an ongoing loan or credit line");
334-
borrowingMutex.lock(borrower, address(loanToken));
335334
require(
336335
creditOracle.status(borrower) == ITrueFiCreditOracle.Status.Eligible,
337336
"FixedTermLoanAgency: Sender is not eligible for loan"
338337
);
339338

340-
uint256 term = loanToken.term();
341-
require(term > 0, "LoanFactory: Loans cannot have instantaneous term of repay");
339+
require(amount > 0, "FixedTermLoanAgency: Loans of amount 0, will not be approved");
340+
require(amount <= borrowLimit(pool, borrower), "FixedTermLoanAgency: Loan amount cannot exceed borrow limit");
341+
342+
require(term > 0, "FixedTermLoanAgency: Loans cannot have instantaneous term of repay");
342343
require(isTermBelowMax(term), "FixedTermLoanAgency: Loan's term is too long");
343344
require(isCredibleForTerm(term), "FixedTermLoanAgency: Credit score is too low for loan's term");
344345

345-
uint256 amount = loanToken.amount();
346-
require(amount > 0, "LoanFactory: Loans of amount 0, will not be approved");
347-
require(amount <= borrowLimit(pool, loanToken.borrower()), "FixedTermLoanAgency: Loan amount cannot exceed borrow limit");
348-
349346
uint256 apy = rate(pool, borrower, amount, term);
350-
// TODO use the above apy calculation and delete the below apy when calling LF2.createFTLALoanToken()
351-
apy = loanToken.apy();
352-
require(apy <= _maxApy, "LoanFactory: Calculated apy is higher than max apy");
347+
require(apy <= _maxApy, "FixedTermLoanAgency: Calculated apy is higher than max apy");
353348

349+
ILoanToken2 loanToken = loanFactory.createFTLALoanToken(pool, borrower, amount, term, apy);
350+
borrowingMutex.lock(borrower, address(loanToken));
354351
poolLoans[pool].push(loanToken);
355352
pool.borrow(amount);
356353
pool.token().safeApprove(address(loanToken), amount);
@@ -415,7 +412,7 @@ contract FixedTermLoanAgency is IFixedTermLoanAgency, UpgradeableClaimable {
415412
uint256 resultPrecision = uint256(10)**decimals;
416413

417414
// loop through loans and sum amount borrowed accounting for precision
418-
ITrueFiPool2[] memory pools = factory.getSupportedPools();
415+
ITrueFiPool2[] memory pools = poolFactory.getSupportedPools();
419416
for (uint8 i = 0; i < pools.length; i++) {
420417
ITrueFiPool2 pool = pools[i];
421418
uint256 poolPrecision = uint256(10)**ITrueFiPool2WithDecimals(address(pool)).decimals();

deploy/truefi2.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ deploy({}, (_, config) => {
119119
trueLender2.initialize(stkTruToken, poolFactory, oneInch, trueFiCreditOracle, AddressZero, borrowingMutex)
120120
})
121121
runIf(ftlAgency.isInitialized().not(), () => {
122-
ftlAgency.initialize(stkTruToken, poolFactory, oneInch, trueFiCreditOracle, AddressZero, borrowingMutex)
122+
ftlAgency.initialize(stkTruToken, poolFactory, oneInch, trueFiCreditOracle, AddressZero, borrowingMutex, loanFactory2)
123123
})
124124
runIf(loanFactory2.isInitialized().not(), () => {
125125
loanFactory2.initialize(poolFactory, trueLender2, ftlAgency, liquidator2, AddressZero, trueFiCreditOracle, borrowingMutex, AddressZero)

0 commit comments

Comments
 (0)