Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: listig usdt #113

Merged
merged 9 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ cache
artifacts
storage_layout
out.html

# Foundry
cache_forge
out
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
4 changes: 4 additions & 0 deletions contracts/interfaces/IIncentivesController.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.4;

import {IScaledBalanceToken} from "./IScaledBalanceToken.sol";

interface IIncentivesController {
/**
* @dev Called by the corresponding asset on any update that affects the rewards distribution
Expand All @@ -13,4 +15,6 @@ interface IIncentivesController {
uint256 totalSupply,
uint256 userBalance
) external;

function configureAssets(IScaledBalanceToken[] calldata _assets, uint256[] calldata _emissionsPerSecond) external;
}
6 changes: 6 additions & 0 deletions contracts/interfaces/IPunks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ interface IPunks {

function punkIndexToAddress(uint256 punkIndex) external view returns (address owner);

function offerPunkForSaleToAddress(
uint256 punkIndex,
uint256 minSalePriceInWei,
address toAddress
) external;

function buyPunk(uint256 punkIndex) external;

function transferPunk(address to, uint256 punkIndex) external;
Expand Down
15 changes: 13 additions & 2 deletions contracts/mock/MintableERC20.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.4;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

/**
* @title ERC20Mintable
* @dev ERC20 minting logic
*/
contract MintableERC20 is ERC20 {
contract MintableERC20 is ERC20, Ownable {
uint8 private _decimals;
mapping(address => uint256) public mintValues;
address public faucet;

constructor(
string memory name,
Expand All @@ -33,10 +35,19 @@ contract MintableERC20 is ERC20 {
* @return A boolean that indicates if the operation was successful.
*/
function mint(uint256 value) public returns (bool) {
if (faucet == address(0)) {
require((mintValues[_msgSender()] + value) <= (1000000 * (10**_decimals)), "MintableERC20: exceed mint limit");
} else {
require(faucet == _msgSender(), "MintableERC20: minting not allowed");
}

mintValues[_msgSender()] += value;
require(mintValues[_msgSender()] < (1000000 * (10**_decimals)), "exceed mint limit");

_mint(_msgSender(), value);
return true;
}

function setFaucet(address faucet_) public onlyOwner {
faucet = faucet_;
}
}
19 changes: 15 additions & 4 deletions contracts/mock/MintableERC721.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.4;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {ERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";

/**
* @title MintableERC721
* @dev ERC721 minting logic
*/
contract MintableERC721 is ERC721Enumerable {
contract MintableERC721 is ERC721Enumerable, Ownable {
string public baseURI;
mapping(address => uint256) public mintCounts;
address public faucet;

constructor(string memory name, string memory symbol) ERC721(name, symbol) {
baseURI = "https://MintableERC721/";
Expand All @@ -22,10 +24,15 @@ contract MintableERC721 is ERC721Enumerable {
* @return A boolean that indicates if the operation was successful.
*/
function mint(uint256 tokenId) public returns (bool) {
require(tokenId < 10000, "exceed mint limit");
if (faucet == address(0)) {
require((mintCounts[_msgSender()] + 1) <= 10, "MintableERC721: exceed mint limit");
} else {
require(faucet == _msgSender(), "MintableERC721: minting not allowed");
}

require(tokenId < 10000, "MintableERC721: exceed max token id");

mintCounts[_msgSender()] += 1;
require(mintCounts[_msgSender()] <= 10, "exceed mint limit");

_mint(_msgSender(), tokenId);
return true;
Expand All @@ -35,7 +42,11 @@ contract MintableERC721 is ERC721Enumerable {
return baseURI;
}

function setBaseURI(string memory baseURI_) public {
function setBaseURI(string memory baseURI_) public onlyOwner {
baseURI = baseURI_;
}

function setFaucet(address faucet_) public onlyOwner {
faucet = faucet_;
}
}
10 changes: 10 additions & 0 deletions contracts/mock/MockIncentivesController.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.4;

import {IScaledBalanceToken} from "../interfaces/IScaledBalanceToken.sol";
import {IIncentivesController} from "../interfaces/IIncentivesController.sol";

contract MockIncentivesController is IIncentivesController {
bool private _handleActionIsCalled;
address private _asset;
uint256 private _totalSupply;
uint256 private _userBalance;
uint256 private _emissionPerSecond;

/**
* @dev Called by the corresponding asset on any update that affects the rewards distribution
Expand All @@ -26,6 +28,14 @@ contract MockIncentivesController is IIncentivesController {
_userBalance = userBalance;
}

function configureAssets(IScaledBalanceToken[] calldata _assets, uint256[] calldata _emissionsPerSeconds)
external
override
{
_asset = address(_assets[0]);
_emissionPerSecond = _emissionsPerSeconds[0];
}

function checkHandleActionIsCorrect(
address asset,
uint256 totalSupply,
Expand Down
5 changes: 4 additions & 1 deletion contracts/protocol/EmergencyTokenRecoveryUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity 0.8.4;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";

import {IPunks} from "../interfaces/IPunks.sol";

Expand All @@ -13,6 +14,8 @@ import {IPunks} from "../interfaces/IPunks.sol";
* @author Bend
**/
abstract contract EmergencyTokenRecoveryUpgradeable is OwnableUpgradeable {
using SafeERC20Upgradeable for IERC20Upgradeable;

event EmergencyEtherTransfer(address indexed to, uint256 amount);

function __EmergencyTokenRecovery_init() internal onlyInitializing {
Expand All @@ -31,7 +34,7 @@ abstract contract EmergencyTokenRecoveryUpgradeable is OwnableUpgradeable {
address to,
uint256 amount
) external onlyOwner {
IERC20Upgradeable(token).transfer(to, amount);
IERC20Upgradeable(token).safeTransfer(to, amount);
}

/**
Expand Down
14 changes: 7 additions & 7 deletions contracts/protocol/PunkGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ contract PunkGateway is IPunkGateway, ERC721HolderUpgradeable, EmergencyTokenRec

function authorizeLendPoolERC20(address[] calldata tokens) external nonReentrant onlyOwner {
for (uint256 i = 0; i < tokens.length; i++) {
IERC20Upgradeable(tokens[i]).approve(address(_getLendPool()), type(uint256).max);
IERC20Upgradeable(tokens[i]).safeApprove(address(_getLendPool()), type(uint256).max);
}
}

Expand Down Expand Up @@ -142,7 +142,7 @@ contract PunkGateway is IPunkGateway, ERC721HolderUpgradeable, EmergencyTokenRec
_depositPunk(punkIndex);

cachedPool.borrow(reserveAsset, amount, address(wrappedPunks), punkIndex, onBehalfOf, referralCode);
IERC20Upgradeable(reserveAsset).transfer(onBehalfOf, amount);
IERC20Upgradeable(reserveAsset).safeTransfer(onBehalfOf, amount);
}

function batchBorrow(
Expand All @@ -164,7 +164,7 @@ contract PunkGateway is IPunkGateway, ERC721HolderUpgradeable, EmergencyTokenRec

cachedPool.borrow(reserveAssets[i], amounts[i], address(wrappedPunks), punkIndexs[i], onBehalfOf, referralCode);

IERC20Upgradeable(reserveAssets[i]).transfer(onBehalfOf, amounts[i]);
IERC20Upgradeable(reserveAssets[i]).safeTransfer(onBehalfOf, amounts[i]);
}
}

Expand Down Expand Up @@ -214,7 +214,7 @@ contract PunkGateway is IPunkGateway, ERC721HolderUpgradeable, EmergencyTokenRec
amount = debt;
}

IERC20Upgradeable(reserve).transferFrom(msg.sender, address(this), amount);
IERC20Upgradeable(reserve).safeTransferFrom(msg.sender, address(this), amount);

(uint256 paybackAmount, bool burn) = cachedPool.repay(address(wrappedPunks), punkIndex, amount);

Expand All @@ -241,7 +241,7 @@ contract PunkGateway is IPunkGateway, ERC721HolderUpgradeable, EmergencyTokenRec

(, , address reserve, ) = cachedPoolLoan.getLoanCollateralAndReserve(loanId);

IERC20Upgradeable(reserve).transferFrom(msg.sender, address(this), bidPrice);
IERC20Upgradeable(reserve).safeTransferFrom(msg.sender, address(this), bidPrice);

cachedPool.auction(address(wrappedPunks), punkIndex, bidPrice, onBehalfOf);
}
Expand All @@ -259,7 +259,7 @@ contract PunkGateway is IPunkGateway, ERC721HolderUpgradeable, EmergencyTokenRec

DataTypes.LoanData memory loan = cachedPoolLoan.getLoan(loanId);

IERC20Upgradeable(loan.reserveAsset).transferFrom(msg.sender, address(this), (amount + bidFine));
IERC20Upgradeable(loan.reserveAsset).safeTransferFrom(msg.sender, address(this), (amount + bidFine));

uint256 paybackAmount = cachedPool.redeem(address(wrappedPunks), punkIndex, amount, bidFine);

Expand All @@ -281,7 +281,7 @@ contract PunkGateway is IPunkGateway, ERC721HolderUpgradeable, EmergencyTokenRec
require(loan.bidderAddress == _msgSender(), "PunkGateway: caller is not bidder");

if (amount > 0) {
IERC20Upgradeable(loan.reserveAsset).transferFrom(msg.sender, address(this), amount);
IERC20Upgradeable(loan.reserveAsset).safeTransferFrom(msg.sender, address(this), amount);
}

uint256 extraRetAmount = cachedPool.liquidate(address(wrappedPunks), punkIndex, amount);
Expand Down
14 changes: 7 additions & 7 deletions contracts/protocol/WrapperGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contract WrapperGateway is

function authorizeLendPoolERC20(address[] calldata tokens) external nonReentrant onlyOwner {
for (uint256 i = 0; i < tokens.length; i++) {
IERC20Upgradeable(tokens[i]).approve(address(_getLendPool()), type(uint256).max);
IERC20Upgradeable(tokens[i]).safeApprove(address(_getLendPool()), type(uint256).max);
}
}

Expand Down Expand Up @@ -116,7 +116,7 @@ contract WrapperGateway is

cachedPool.borrow(reserveAsset, amount, address(wrappedToken), nftTokenId, onBehalfOf, referralCode);

IERC20Upgradeable(reserveAsset).transfer(onBehalfOf, amount);
IERC20Upgradeable(reserveAsset).safeTransfer(onBehalfOf, amount);
}

function batchBorrow(
Expand All @@ -138,7 +138,7 @@ contract WrapperGateway is

cachedPool.borrow(reserveAssets[i], amounts[i], address(wrappedToken), nftTokenIds[i], onBehalfOf, referralCode);

IERC20Upgradeable(reserveAssets[i]).transfer(onBehalfOf, amounts[i]);
IERC20Upgradeable(reserveAssets[i]).safeTransfer(onBehalfOf, amounts[i]);
}
}

Expand Down Expand Up @@ -189,7 +189,7 @@ contract WrapperGateway is
amount = debt;
}

IERC20Upgradeable(reserve).transferFrom(msg.sender, address(this), amount);
IERC20Upgradeable(reserve).safeTransferFrom(msg.sender, address(this), amount);

(uint256 paybackAmount, bool burn) = cachedPool.repay(address(wrappedToken), nftTokenId, amount);

Expand All @@ -216,7 +216,7 @@ contract WrapperGateway is

(, , address reserve, ) = cachedPoolLoan.getLoanCollateralAndReserve(loanId);

IERC20Upgradeable(reserve).transferFrom(msg.sender, address(this), bidPrice);
IERC20Upgradeable(reserve).safeTransferFrom(msg.sender, address(this), bidPrice);

cachedPool.auction(address(wrappedToken), nftTokenId, bidPrice, onBehalfOf);
}
Expand All @@ -234,7 +234,7 @@ contract WrapperGateway is

DataTypes.LoanData memory loan = cachedPoolLoan.getLoan(loanId);

IERC20Upgradeable(loan.reserveAsset).transferFrom(msg.sender, address(this), (amount + bidFine));
IERC20Upgradeable(loan.reserveAsset).safeTransferFrom(msg.sender, address(this), (amount + bidFine));

uint256 paybackAmount = cachedPool.redeem(address(wrappedToken), nftTokenId, amount, bidFine);

Expand All @@ -256,7 +256,7 @@ contract WrapperGateway is
require(loan.bidderAddress == _msgSender(), "WrapperGateway: caller is not bidder");

if (amount > 0) {
IERC20Upgradeable(loan.reserveAsset).transferFrom(msg.sender, address(this), amount);
IERC20Upgradeable(loan.reserveAsset).safeTransferFrom(msg.sender, address(this), amount);
}

uint256 extraRetAmount = cachedPool.liquidate(address(wrappedToken), nftTokenId, amount);
Expand Down
20 changes: 15 additions & 5 deletions deployments/deployed-contracts-goerli.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@
"deployer": "0xafF5C36642385b6c7Aaf7585eC785aB2316b5db6"
},
"PunkGatewayImpl": {
"address": "0x675B54905Ae457D9B7BcA72B58a7CC33AD3AB514"
"address": "0xF322391B5444fC4B7Ad43859E4b0B0ddA75C31f9"
},
"PunkGateway": {
"address": "0xa7076550Ee79DB0320BE98f89D775797D859140c",
"deployer": "0xafF5C36642385b6c7Aaf7585eC785aB2316b5db6"
"address": "0xa7076550Ee79DB0320BE98f89D775797D859140c"
},
"WalletBalanceProvider": {
"address": "0xe54EEF2aFb3cBdBBe58370F33296d533a34123E5",
Expand All @@ -133,10 +132,21 @@
"deployer": "0xafF5C36642385b6c7Aaf7585eC785aB2316b5db6"
},
"KodaGatewayImpl": {
"address": "0xA7bb6431BF998D4e3380ed73DcB226e23E37AA27"
"address": "0x683a9367e79934BD196D05A2AdD30a6C58Aa0ce0"
},
"KodaGateway": {
"address": "0x3fa746EcDC1C53c7657a57c71bFaB497be2e0BF5",
"address": "0x3fa746EcDC1C53c7657a57c71bFaB497be2e0BF5"
},
"MintableERC20": {
"address": "0x8096Fd3B381164af8421F25c84063B8afC637fE5",
"deployer": "0xafF5C36642385b6c7Aaf7585eC785aB2316b5db6"
},
"USDT": {
"address": "0x8096Fd3B381164af8421F25c84063B8afC637fE5",
"deployer": "0xafF5C36642385b6c7Aaf7585eC785aB2316b5db6"
},
"rateStrategyStableThree": {
"address": "0x124A8d7D5E8C72e0951D1B247bDac02640914b19",
"deployer": "0xafF5C36642385b6c7Aaf7585eC785aB2316b5db6"
}
}
11 changes: 7 additions & 4 deletions deployments/deployed-contracts-main.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"address": "0x3B968D2D299B895A5Fcf3BBa7A64ad0F566e6F88"
},
"PunkGatewayImpl": {
"address": "0x70a987A0E1ea971728A1F872eacD764eDAE190B1"
"address": "0x0Fccf4bB61c78CE7dEF3A1e84772Fe6d3b4A450a"
},
"PunkGateway": {
"address": "0xeD01f8A737813F0bDA2D4340d191DBF8c2Cbcf30"
Expand All @@ -129,10 +129,13 @@
"deployer": "0x868964fa49a6fd6e116FE82c8f4165904406f479"
},
"KodaGatewayImpl": {
"address": "0x3837Ddc0b0Ee70aA9007dB6bED3f40b9cAEbd202"
"address": "0x228fEb12E514d9f547B2f5C41449a5F4CbA93a86"
},
"KodaGateway": {
"address": "0x56ECe8EDba529943b9A8ED966253b1F5ac54BF55",
"address": "0x56ECe8EDba529943b9A8ED966253b1F5ac54BF55"
},
"rateStrategyUSDT230628": {
"address": "0x8B8BefFDf3aC2C32aF746DaFaE49E085f4D07267",
"deployer": "0x868964fa49a6fd6e116FE82c8f4165904406f479"
}
}
}
13 changes: 13 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[profile.default]
src = 'contracts'
out = 'out'
libs = ['node_modules', 'lib']
test = 'test'
cache_path = 'cache_forge'
gas_reports = [""]

[fmt]
line_length = 120

[fuzz]
runs = 32
Loading
Loading