Skip to content

Instantly share code, notes, and snippets.

@luisivan
Last active June 14, 2022 14:30
Show Gist options
  • Save luisivan/3ec79d8bc1e28ce781bb58ae7f8be12f to your computer and use it in GitHub Desktop.
Save luisivan/3ec79d8bc1e28ce781bb58ae7f8be12f to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: UNLICENSED
pragma solidity =0.8.10;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
contract Loan is Initializable, Ownable {
using SafeTransferLib for ERC20;
error NotLender();
error IncorrectAmount();
event CollateralAdded(address account, uint256 collateralAmount);
event CapitalAdded(address account, uint256 capitalAmount);
event RepaidAmount(address account, uint256 repaidAmount);
event CollateralClaimed(address account, uint256 claimedAmount);
event CollateralRecovered(address account, uint256 recoveredAmount);
ERC20 public collateralToken;
ERC20 public loanToken;
address public lender;
address public borrower;
uint256 public collateralAmount;
uint256 public loanAmount;
uint256 public expiryBlock;
uint256 public interest;
uint256 public repaidAmount;
bool public capitalDeposited;
function initialize(
address _lender,
address _borrower,
ERC20 _collateralToken,
uint256 _collateralAmount,
ERC20 _loanToken,
uint256 _loanAmount,
uint256 _expiryBlock,
uint256 _interest
) external initializer {
lender = address(_lender);
borrower = address(_borrower);
collateralToken = ERC20(_collateralToken);
collateralAmount = _collateralAmount;
loanToken = ERC20(_loanToken);
loanAmount = _loanAmount;
expiryBlock = _expiryBlock;
interest = _interest;
repaidAmount = 0;
capitalDeposited = false;
}
function depositCollateral(
uint256 _amount,
) external virtual onlyOwner {
if (_amount != collateralAmount) revert IncorrectAmount();
collateralToken.safeTransferFrom(msg.sender, address(this), _amount);
emit CollateralAdded(msg.sender, _amount);
}
function depositCapital(
uint256 _amount,
) external virtual {
if (_amount != loanAmount) revert IncorrectAmount();
loanToken.safeTransferFrom(msg.sender, borrower, _amount);
capitalDeposited = true;
emit CapitalAdded(msg.sender, _amount);
}
function repay(
uint256 _amount,
) external virtual {
loanToken.safeTransferFrom(msg.sender, lender, _amount * (1 + _interest));
repaidAmount = repaidAmount + _amount;
emit RepaidAmount(msg.sender, _amount);
}
function settle() external virtual {
if (!capitalDeposited || block.number >= endBlock) {
uint256 claimableAmount = (repaidAmount / loanAmount) * collateralAmount;
if (!capitalDeposited) {
claimableAmount = 0;
}
collateralToken.safeTransfer(lender, claimableAmount);
collateralToken.safeTransfer(borrower, loanAmount - claimableAmount);
emit CollateralClaimed(lender, claimableAmount);
emit CollateralRecovered(borrower, loanAmount - claimableAmount);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment