DECLARATIONERROR: UNDECLARED IDENTIFIER when I compile from Truffle - solidity

I am trying to create a Credist Score Function in a Loan Management Smart Contract using solidity, but I keep getting this undeclared identifier error when I compile on remix browser IDE and truffle. How can I solve this problem please?
I have attached my code here:
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "../IERC20.sol";
import "./Loan.sol";
interface TrustTokenInterface {
function isTrustee(address) external view returns (bool);
function balanceOf(address) external view returns (uint256);
}
interface ProposalManagementInterface {
function memberId(address) external view returns (uint256);
function contractFee() external view returns (uint256);
function setLoanManagement(address) external;
function transferTokensFrom(address, address, uint256) external returns (bool);
}
interface LoanInterface {
struct LoanParams {
address lender;
address borrower;
bool initiatorVerified;
uint256 principalAmount;
uint256 paybackAmount;
uint256 contractFee;
string purpose;
address collateralToken;
uint256 collateralAmount;
uint256 duration;
uint256 effectiveDate;
}
function managementAcceptLoanOffer(address) external;
function managementAcceptLoanRequest(address) external;
function managementReturnCollateral() external;
function managementDefaultOnLoan() external;
function cleanUp() external;
function borrower() external view returns (address);
function lender() external view returns (address);
function getLoanParameters() external view returns (LoanParams memory);
function getLoanStatus() external view returns (uint8);
function refreshAndGetLoanStatus() external returns (uint8);
}
contract LoanManagement {
// Loan platform settings.
address payable private trustToken;
address private proposalManagement;
// Loan management variables.
mapping(address => uint256) private userRequestCount;
mapping(address => uint256) private userOfferCount;
mapping(address => bool) private validLoanAd;
mapping(address => bool) private openLoan;
address[] private loanRequests;
address[] private loanOffers;
// Credit rating system variables.
mapping(address => uint256) public borrowerRatings;
mapping(address => uint256) public lenderRatings;
// Event for when a borrower requests a loan.
event LoanRequested();
// Event for when a lender offers a loan.
event LoanOffered();
// Event for when a borrower accepts a loan offer, or a lender accepts a loan request.
event LoanGranted();
// Event for a borrower deposits collateral to the loan.
// Event for when a borrower withdraws the loan's value.
event LoanDisbursed();
// Event for when a borrower repays or a lender withdraws collateral.
event LoanSettled();
/**
* #notice Creates an instance of the LoanManagement contract.
* #param _trustToken Address of the TrustToken
* #param _proposalManagement Address of the ProposalManagement
*/
constructor(
address payable _trustToken,
address _proposalManagement) public {
trustToken = _trustToken;
proposalManagement = _proposalManagement;
ProposalManagementInterface(proposalManagement).setLoanManagement(address(this));
}
/**
* #notice Creates a request from a borrower for a new loan.
* #param _principalAmount Loan principal amount in Wei
* #param _paybackAmount Loan repayment amount (in Wei?)
* #param _purpose Purpose(s) the loan will be used for
* #param _collateralToken Address of the token to be used for collateral
* #param _collateralAmount Amount of collateral (denominated in _collateralToken) required
* #param _duration Length of time borrower has to repay the loan from when the lender deposits the principal
*/
function createLoanRequest(
uint256 _principalAmount,
uint256 _paybackAmount,
string memory _purpose,
address _collateralToken,
uint256 _collateralAmount,
uint256 _duration) public {
// Validate the input parameters.
require(_principalAmount > 0, "Principal amount must be greater than 0");
require(_paybackAmount > _principalAmount, "Payback amount must be greater than principal");
require(userRequestCount[msg.sender] < 5, "Too many loan requests made");
require(_collateralToken == address(trustToken), "Only BBET is currently supported as a collateral token");
require(_duration >= 60 * 60 * 12, "Loan duration must be at least 12 hours");
// Check if borrower is a verified member.
bool borrowerVerified = TrustTokenInterface(address(trustToken)).isTrustee(msg.sender);
borrowerVerified = borrowerVerified || ProposalManagementInterface(proposalManagement).memberId(msg.sender) != 0;
require(borrowerVerified, "Must be a DFND holder to request loans");
// Get contract fee.
uint256 contractFee = ProposalManagementInterface(proposalManagement).contractFee();
// Check if the borrower has enough collateral.
require(IERC20(_collateralToken).balanceOf(msg.sender) > _collateralAmount, "Insufficient collateral in account");
// Create new Loan contract.
address loan = address(
new Loan(
payable(proposalManagement), trustToken, address(0), msg.sender,
_principalAmount, _paybackAmount, contractFee, _purpose,
_collateralToken, _collateralAmount, _duration
)
);
// Update number of active requests by the borrower.
userRequestCount[msg.sender]++;
// Add new loan request to management structures.
loanRequests.push(loan);
// Mark requested loan as a valid ad (request/offer).
validLoanAd[loan] = true;
// Trigger LoanRequested event.
// TODO emit LoanRequested();
// TODO In web3.js: Ask user to approve spending of collateral by management contract.
}
/**
* #notice Creates an offer by a lender for a new loan.
* #param _principalAmount Loan principal amount in Wei
* #param _paybackAmount Loan repayment amount (in Wei?)
* #param _purpose Purpose(s) the loan will be used for
* #param _collateralToken Address of the token to be used for collateral
* #param _collateralAmount Amount of collateral (denominated in _collateralToken) required
* #param _duration Length of time borrower has to repay the loan from when the lender deposits the principal
*/
function createLoanOffer(
uint256 _principalAmount,
uint256 _paybackAmount,
string memory _purpose,
address _collateralToken,
uint256 _collateralAmount,
uint256 _duration) public {
// Validate the input parameters.
require(_principalAmount > 0, "Principal amount must be greater than 0");
require(_paybackAmount > _principalAmount, "Payback amount must be greater than principal");
require(userOfferCount[msg.sender] < 5, "Too many loan offers made");
require(_collateralToken == address(trustToken), "Only BBET is currently supported as a collateral token");
require(_duration >= 60 * 60 * 12, "Loan duration must be at least 12 hours");
// Check if lender is a verified member.
bool lenderVerified = TrustTokenInterface(address(trustToken)).isTrustee(msg.sender);
lenderVerified = lenderVerified || ProposalManagementInterface(proposalManagement).memberId(msg.sender) != 0;
require(lenderVerified, "Must be a DFND holder to offer loans");
// Get contract fee.
uint256 contractFee = ProposalManagementInterface(proposalManagement).contractFee();
// Make sure the lender has enough DFND to pay the principal.
require(IERC20(trustToken).balanceOf(msg.sender) > _principalAmount, "Insufficient balance to offer this loan");
// Create new Loan contract.
address loan = address(
new Loan(
payable(proposalManagement), trustToken, msg.sender, address(0),
_principalAmount, _paybackAmount, contractFee, _purpose,
_collateralToken, _collateralAmount, _duration
)
);
// Update number of offers made by the lender.
userOfferCount[msg.sender]++;
// Add new loan offer management structures.
loanOffers.push(loan);
// Mark offered loan as a valid ad (request/offer).
validLoanAd[loan] = true;
// Trigger LoanOffered event.
// TODO emit LoanOffered();
}
/**
* #notice Borrower accepts loan offer; collateral transfers from borrower to loan; principal transfers from lender to borrower.
* #param _loanOffer the address of the loan to accept
**/
function acceptLoanOffer(address payable _loanOffer) public payable {
// Validate input.
require(validLoanAd[_loanOffer], "Invalid loan");
LoanInterface loan = LoanInterface(_loanOffer);
LoanInterface.LoanParams memory loanParams = loan.getLoanParameters();
// Check if user is verified.
bool borrowerVerified = TrustTokenInterface(address(trustToken)).isTrustee(msg.sender);
borrowerVerified = borrowerVerified || ProposalManagementInterface(proposalManagement).memberId(msg.sender) != 0;
require(borrowerVerified, "DFND balance insufficient or account not verified to accept loan offers");
// Check if borrower has approved spending of collateral.
if (loanParams.collateralAmount > 0) {
require(IERC20(loanParams.collateralToken).allowance(msg.sender, _loanOffer) < loanParams.collateralAmount, "Borrower must approve spending of collateral before accepting the loan");
}
// Check if lender has enough DFND to accept.
if (TrustTokenInterface(address(trustToken)).balanceOf(loanParams.lender) >= loanParams.principalAmount) {
cancelLoanAd(_loanOffer, msg.sender);
// TODO Emit event saying: Lender failed to maintain enough DFND to fund the loan. Loan offer is now canceled
return;
}
// Transfer borrower's collateral to loan.
if (loanParams.collateralAmount > 0) {
IERC20(loanParams.collateralToken).transferFrom(msg.sender, _loanOffer, loanParams.collateralAmount);
}
// Transfer principal from lender to borrower.
ProposalManagementInterface(proposalManagement).transferTokensFrom(loanParams.lender, msg.sender, loanParams.principalAmount);
// Update loan status.
Loan(_loanOffer).managementAcceptLoanOffer(msg.sender);
// Remove loan offer from management structures.
removeLoanOffer(_loanOffer, loanParams.borrower);
openLoan[_loanOffer] = true;
// TODO Emit the proper event for frontend to notify loan counterparty.
// TODO emit LoanGranted();
}
/**
* #notice Lender accepts loan request; collateral transfers from borrower to loan; principal transfers from lender to borrower.
* #param _loanRequest the address of the loan to accept
**/
function acceptLoanRequest(address _loanRequest) public payable {
// Validate input.
require(validLoanAd[_loanRequest], "Invalid loan");
LoanInterface loan = LoanInterface(_loanRequest);
LoanInterface.LoanParams memory loanParams = loan.getLoanParameters();
// Check if user is verified.
bool lenderVerified = TrustTokenInterface(address(trustToken)).isTrustee(msg.sender);
lenderVerified = lenderVerified || ProposalManagementInterface(proposalManagement).memberId(msg.sender) != 0;
require(lenderVerified, "DFND balance insufficient or account not verified");
// Check if lender has enough DFND to accept.
require(TrustTokenInterface(address(trustToken)).balanceOf(msg.sender) >= loanParams.principalAmount, "DFND balance insufficient");
// Check if borrower has approved spending of collateral.
if (loanParams.collateralAmount > 0) {
if (IERC20(loanParams.collateralToken).allowance(loanParams.borrower, _loanRequest) < loanParams.collateralAmount) {
cancelLoanAd(_loanRequest, msg.sender);
// TODO Emit event saying: Borrower failed to put up collateral. Loan was canceled
return;
}
}
// Transfer borrower's collateral to loan.
if (loanParams.collateralAmount > 0) {
IERC20(loanParams.collateralToken).transferFrom(address(loanParams.borrower), _loanRequest, loanParams.collateralAmount);
}
// Transfer principal from lender to borrower.
ProposalManagementInterface(proposalManagement).transferTokensFrom(msg.sender, loanParams.borrower, loanParams.principalAmount);
// Update loan status.
Loan(_loanRequest).managementAcceptLoanRequest(msg.sender);
// Remove loan request from management structures.
removeLoanRequest(_loanRequest, loanParams.borrower);
openLoan[_loanRequest] = true;
// TODO Emit the proper event for frontend to notify loan counterparty.
// TODO emit LoanGranted();
}
/**
* #notice Transfers DFND from the borrower to the lender and returns borrower's collateral.
*/
function repayLoan(address _loan) public {
// Validate parameters.
LoanInterface loan = LoanInterface(_loan);
LoanInterface.LoanParams memory loanParams = loan.getLoanParameters();
require(msg.sender == loanParams.borrower, "Only the borrower may repay their loan");
// Check if borrower has sufficient funds to repay loan and fee.
require(TrustTokenInterface(trustToken).balanceOf(msg.sender) >= loanParams.paybackAmount + loanParams.contractFee,
"Insufficient balance");
// Transfer principal to lender.
ProposalManagementInterface(proposalManagement).transferTokensFrom(msg.sender, loanParams.lender, loanParams.paybackAmount);
// Transfer contract fee management contract.
ProposalManagementInterface(proposalManagement).transferTokensFrom(msg.sender, address(this), loanParams.contractFee);
// Transfer collateral to lender.
if (loanParams.collateralAmount > 0) {
loan.managementReturnCollateral();
}
// Destroy loan.
openLoan[_loan] = false;
loan.cleanUp();
// TODO Increase credit score if loan was repaid on time.
// TODO Lower credit score if loan was repaid late.
// TODO Emit the proper event and respond to it.
// TODO emit LoanRepaid();
}
/**
* #notice Checks if loan expired, penalizes borrower for failure to repay, gives collateral to the lender.
*/
function defaultOnLoan(address _loan) public {
// Validate parameters.
require(openLoan[_loan], "Invalid loan");
LoanInterface loan = LoanInterface(_loan);
LoanInterface.LoanParams memory loanParams = loan.getLoanParameters();
require(msg.sender == loanParams.lender, "Only the lender may claim the loan's collateral");
// Check if the loan term has expired.
uint8 loanStatus = loan.refreshAndGetLoanStatus();
require(loanStatus == 2, "Cannot claim collateral until the loan has reached maturity");
// Send collateral from loan contract to lender.
if (loanParams.collateralAmount > 0) {
loan.managementDefaultOnLoan();
}
// Mark loan as completed.
openLoan[_loan] = false;
loan.cleanUp();
}
function creditScore(address _loan, address _sender, address _lender) public {
// Increase/decrease borrower credit score.
if (loanParams.effectiveDate + loanParams.duration < block.timestamp + 60) {
// Increase borrower credit score if loan was repaid on time.
uint256 borrowerScore = borrowerRatings[msg.sender];
borrowerScore += (borrowerScore < 100) ? 50 : (300 - borrowerScore) / 4;
// TODO ignore for now: add additional points for amount of ETH borrowed.
// Save the borrower's new score.
borrowerRatings[msg.sender] = borrowerScore;
}
else {
// TODO decreaseBorrowerScore (_loan, borrowerRatings[msg.sender]);
}
// TODO Increase/decrease lender credit score.
// TODO increase Lender credit score if loan was repaid late.
if (loanParams.effectiveDate + loanParams.duration < block.timestamp + 60) {
// Increase lender credit score if loan was not repaid on time.
uint256 lenderScore = lenderRatings[loanParams.lender];
lenderScore += (lenderScore < 100) ? 50 : (300 - lenderScore) / 4;
// TODO ignore for now: add additional points for amount of ETH borrowed.
// Save the borrower's new score.
lenderRatings[loanParams.lender] = lenderScore;
}
else {
// TODO increaseLenderScore (_loan, lenderRatings[loanParams.lender]);
}
}
/**
* #notice Cancels the loan request/offer.
* Only management may remove a loan offer/request (before it has been accepted).
* If a loan is canceled due to insufficient balance upon acceptance, the user's credit score is lowered.
* #param _loan Address of the loan request/offer to cancel
* #param _sender Address whose action triggered the loan to be canceled (counterparty will have credit score affected)
*/
function cancelLoanAd(address _loan, address _sender) public {
// Validate input.
require(msg.sender == proposalManagement || msg.sender == address(this), "Only admin may cancel a loan ad");
require(validLoanAd[_loan], "Loan request/offer is invalid, either because it does not exist or has already gone into effect");
// Get loan parameters and state.
LoanInterface loanVar = LoanInterface(_loan);
LoanInterface.LoanParams memory loanParams = loanVar.getLoanParameters();
uint8 loanStatus = loanVar.getLoanStatus();
// Destroy the loan contract.
loanVar.cleanUp();
// Remove the loan ad from management variables.
require(loanParams.borrower == address(0) || loanParams.lender == address(0), "INVALID LOAN STATE/PARAMS");
if (loanParams.borrower == address(0)) {
removeLoanOffer(_loan, loanParams.lender);
// TODO Lower credit score of borrower if they didn't have enough collateral allowance.
} else {
removeLoanRequest(_loan, loanParams.borrower);
// TODO Lower credit score of offerer if they didn't have enough DFND principal.
}
// TODO Use correct event, if it's even needed.
// TODO emit LoanRequestCanceled();
}
/**
* #notice Removes the loan offer from the management structures.
*/
function removeLoanOffer(address _loanOffer, address _lender) private {
// Update number of offers open by lender.
userOfferCount[_lender]--;
// Mark loan offer as invalid.
validLoanAd[_loanOffer] = false;
// Find index of loan offer.
uint idx = loanOffers.length;
bool idxFound = false;
while (true) {
idx--;
if (loanOffers[idx] == _loanOffer) {
idxFound = true;
break;
}
}
// Remove loan offer from array by moving back all other offers after its index.
if (idxFound) {
while (idx < loanOffers.length - 1) {
loanOffers[idx] = loanOffers[idx + 1];
idx++;
}
loanOffers.pop();
}
}
/**
* #notice Removes the loan request from the management structures.
*/
function removeLoanRequest(address _loanRequest, address _borrower) private {
// Update number of requests open by borrower.
userRequestCount[_borrower]--;
// Mark loan request as invalid.
validLoanAd[_loanRequest] = false;
// Find index of loan request.
uint idx = loanRequests.length;
bool idxFound = false;
while (idx > 0) {
idx--;
if (loanRequests[idx] == _loanRequest) {
idxFound = true;
break;
}
}
// Remove loan request from array by moving back all other requests after its index.
if (idxFound) {
while (idx < loanRequests.length - 1) {
loanRequests[idx] = loanRequests[idx + 1];
idx++;
}
loanRequests.pop();
}
}
/**
* #notice Gets all open loan requests.
* #return An array of all open loan requests
*/
function getLoanRequests() public view returns (address[] memory) {
return loanRequests;
}
/**
* #notice Gets all open loan offers.
* #return An array of all open loan offers
*/
function getLoanOffers() public view returns (address[] memory) {
return loanOffers;
}
/**
* #notice Gets all loan parameters except trustToken and proposalManagement.
* #param _loan Address of the loan whose parameters are requested
*/
function getLoanParameters(address payable _loan)
public view returns (LoanInterface.LoanParams memory) {
return LoanInterface(_loan).getLoanParameters();
}
/**
* #notice Gets integer describing status of the loan.
* #return loanStatus == 0: loan offer/request made.
* 1: loan offer/request accepted. principal & collateral automatically transferred.
* 2: loan defaulted. lender has claimed the collateral after the loan expired without repayment.
*/
function getLoanStatus(address _loan)
public view returns (uint8 loanStatus) {
return LoanInterface(_loan).getLoanStatus();
}
/**
* #notice Gets integer describing status of the loan. First, checks if the loan has defaulted.
* #return loanStatus == 0: loan offer/request made.
* 1: loan offer/request accepted. principal & collateral automatically transferred.
* 2: loan defaulted. lender has claimed the collateral after the loan expired without repayment.
*/
function refreshAndGetLoanStatus(address _loan)
public returns (uint8 loanStatus) {
return LoanInterface(_loan).refreshAndGetLoanStatus();
}
}
strong text

Related

Having errors with my "Withdraw" function in Solidity

pragma solidity ^0.8.0;
//using safe math
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";
import "hardhat/console.sol";
contract TimeLock {
/*
Functions to implement
//deposit
//withdraw
//increase timelock
//view time left
*/
/*
need to store balance per user and time per user
*/
using SafeMath for uint;
mapping(address => uint) public balancePerUser;
mapping(address => uint) public timeLeftPerUser;
function deposit( uint amount) external payable {
if(balancePerUser[msg.sender] == 0)
{
balancePerUser[msg.sender] = balancePerUser[msg.sender].add(amount);
timeLeftPerUser[msg.sender] = timeLeftPerUser[msg.sender] + block.timestamp + 8 seconds;
}
else {
balancePerUser[msg.sender] = balancePerUser[msg.sender].add(amount);
timeLeftPerUser[msg.sender] = timeLeftPerUser[msg.sender] + 8 seconds;
}
}
function increaseTimeLock( uint timeInSeconds) public {
timeLeftPerUser[msg.sender] = timeLeftPerUser[msg.sender].add(timeInSeconds);
}
function viewTimeLeft() public view returns (uint256) {
return timeLeftPerUser[msg.sender].sub(block.timestamp);
}
function checkBalance() public view returns (uint) {
return balancePerUser[msg.sender];
}
function withdraw() public payable {
// check that the sender has ether deposited in this contract in the mapping and the balance is >0
require(balancePerUser[msg.sender] > 0, "insufficient funds");
require(block.timestamp > timeLeftPerUser[msg.sender], "lock time has not expired");
// update the balance
uint amount = balancePerUser[msg.sender];
balancePerUser[msg.sender] = 0;
// send the ether back to the sender
payable(msg.sender).transfer(amount);
}
}
I initally deposit some money using the deposit function but upon using the withdraw function I get the following error. Can
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
Would appreciate any help with the same. Thanks!

Implementing a Tax Feature in an ERC20 token

Good day Everyone, I am trying to implement a tax feature in an ERC20 token.
I successfully implemented something similar to a project that involved the creation of a TRC20 token using the code below as a reference:
pragma solidity ^0.6.0;
contract TransfertTokenAndPercentageToTargetAddress{
// pay 1% of all transactions to target address
address payable target = TUEtmARJ2m147RDJ5hy37mhZhEqx2Fnv8r; // I converted the tron address, I didn't use it as shown
// state variables for your token to track balances and to test
mapping (address => uint) public balanceOf;
uint public totalSupply;
// create a token and assign all the tokens to the creator to test
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = totalSupply;
}
// the token transfer function with the addition of a 1% share that
// goes to the target address specified above
function transfer(address _to, uint amount) public {
// calculate the share of tokens for your target address
uint shareForX = amount/100;
// save the previous balance of the sender for later assertion
// verify that all works as intended
uint senderBalance = balanceOf[msg.sender];
// check the sender actually has enough tokens to transfer with function
// modifier
require(senderBalance >= amount, 'Not enough balance');
// reduce senders balance first to prevent the sender from sending more
// than he owns by submitting multiple transactions
balanceOf[msg.sender] -= amount;
// store the previous balance of the receiver for later assertion
// verify that all works as intended
uint receiverBalance = balanceOf[_to];
// add the amount of tokens to the receiver but deduct the share for the
// target address
balanceOf[_to] += amount-shareForX;
// add the share to the target address
balanceOf[target] += shareForX;
// check that everything works as intended, specifically checking that
// the sum of tokens in all accounts is the same before and after
// the transaction.
assert(balanceOf[msg.sender] + balanceOf[_to] + shareForX ==
senderBalance + receiverBalance);
}
}
Then I tried to follow the same approach for an ERC20 token using the template from openzeppelin: https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20
The following code shows the result of the modification:
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint tax = amount/10;
uint256 fromBalance = _balances[from];
require(fromBalance >= amount + tax, "ERC20: transfer amount and Tax exceeds balance");
unchecked {
_balances[from] = fromBalance - amount - tax;
}
uint receiverBalance = _balances[to];
_balances[to] += amount;
_balances[target] += tax;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
// assert(_balances[from] + _balances[to] + tax == fromBalance + receiverBalance);
}
The token was successfully minted but the transfer function won't work. Any suggestions are highly appreciated.

uint256 input in RemixIDE

I'm trying to learn developing my first smart contract in order to use flash loans on aave. I have a problem regarding the amount input for the transaction.
I've a function asking for the amount of token I need and the type is uint256. When I type 10 I only receive 0.0000000000000001 by the flash loan. Why? Maybe it's a stupid question but I'm not understanding what's wrong.
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
import { FlashLoanReceiverBase } from "./FlashLoanReceiverBase.sol";
import { ILendingPool, ILendingPoolAddressesProvider, IERC20 } from "./Interfaces.sol";
import { SafeMath } from "./Libraries.sol";
import "./Ownable.sol";
/*
* A contract that executes the following logic in a single atomic transaction:
*
*
*/
contract BatchFlashDemo is FlashLoanReceiverBase, Ownable {
ILendingPoolAddressesProvider provider;
using SafeMath for uint256;
uint256 flashDaiAmt0;
address lendingPoolAddr;
// mumbai reserve asset addresses
address mumbaiDai = 0x001B3B4d0F3714Ca98ba10F6042DaEbF0B1B7b6F;
// intantiate lending pool addresses provider and get lending pool address
constructor(ILendingPoolAddressesProvider _addressProvider) FlashLoanReceiverBase(_addressProvider) public {
provider = _addressProvider;
lendingPoolAddr = provider.getLendingPool();
}
/**
This function is called after your contract has received the flash loaned amount
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{
/*
*
*
*/
// Approve the LendingPool contract allowance to *pull* the owed amount
// i.e. AAVE V2's way of repaying the flash loan
for (uint i = 0; i < assets.length; i++) {
uint amountOwing = amounts[i].add(premiums[i]);
IERC20(assets[i]).approve(address(_lendingPool), amountOwing);
}
return true;
}
/*
* This function is manually called to commence the flash loans sequence
*/
function executeFlashLoans(uint256 _flashDaiAmt0) public onlyOwner {
address receiverAddress = address(this);
// the various assets to be flashed
address[] memory assets = new address[](1);
assets[0] = mumbaiDai;
// the amount to be flashed for each asset
uint256[] memory amounts = new uint256[](1);
amounts[0] = _flashDaiAmt0;
flashDaiAmt0 = _flashDaiAmt0;
// 0 = no debt, 1 = stable, 2 = variable
uint256[] memory modes = new uint256[](1);
modes[0] = 0;
address onBehalfOf = address(this);
bytes memory params = "";
uint16 referralCode = 0;
_lendingPool.flashLoan(
receiverAddress,
assets,
amounts,
modes,
onBehalfOf,
params,
referralCode
);
}
/*
* Rugpull all ERC20 tokens from the contract
*/
function rugPull() public payable onlyOwner {
// withdraw all ETH
msg.sender.call{ value: address(this).balance }("");
// withdraw all x ERC20 tokens
IERC20(mumbaiDai).transfer(msg.sender, IERC20(mumbaiDai).balanceOf(address(this)));
}
}
I'm deploying passing this address as parameter:
0x178113104fEcbcD7fF8669a0150721e231F0FD4B
it is the Lending Pool Addresses Provider contract taken from here: https://docs.aave.com/developers/v/2.0/deployed-contracts/matic-polygon-market.
When I try asking for more than 1000tokens I get the error. Hope this helps to reproduce.
EVM doesn't support decimal numbers. So a common approach is to declare a number of decimals in the contract, and then include them with the stored values.
Example:
When a contract uses 2 decimals, value of 1 is stored as 100.
Aave protocol works with ERC20 tokens, where the standard defines a function named decimals() to return a number of decimal places.

BEP-20/ERC20 - how to add Tax fees when token is transfer?

Full Source:https://github.com/laronlineworld/NewToken/blob/main/NewToken.sol
This token only deduct tax when selling on dex and tax goes to specific address and the transfer doesn't take any fee.
How to add fee when token was transfer? And fees will go to specific address.
Summary: Tokenomics will be BUY:0% SELL:5% TRANSFER OF TOKEN:5%. Is this possible?
/**
* #dev Moves `amount` of tokens from `sender` to `recipient`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance.sub(amount);
}
bool takeFee = true;
if (_isExcludedFromFee[sender]) {
takeFee = false;
}
if(recipient==pairAddress&&takeFee){
uint256 taxFee = amount.mul(dexTaxFee).div(10000);
_balances[taxAddress] = _balances[taxAddress].add(taxFee);
emit Transfer(sender, taxAddress, taxFee);
amount = amount.sub(taxFee);
}
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
this question has already been answered here: Is it possible to reserve an address on Solidity smart contract creation for taxes collection?
To resume, you need to change the logic of the transfer() function. But be careful as it will break on most dex because it's not an ERC20 token anymore.

When deploying a smart contract, isn't the "owner" of the contract (by default) the one who deploys it?

I am trying to use a function in a flashloan contract that uses the onlyOwner modifier. When I send the flashloan transaction, I get returned the error: "caller is not the owner".
I am using the same account that I used to create the contract when running this flash loan, so I'm not sure why it's not recognizing me as the owner.
You can see here that it is the same address to create the contract and to send the failed transaction.
https://kovan.etherscan.io/address/0x91109bde85e0ab631d1983ce07b910ce4e99078a
Click on the first transaction there ^^ to see the error message.
code of onlyOwner modifier: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol
Contract file
pragma solidity ^0.6.6;
import "./aave/FlashLoanReceiverBaseV2.sol";
import "../../interfaces/v2/ILendingPoolAddressesProviderV2.sol";
import "../../interfaces/v2/ILendingPoolV2.sol";
contract FlashloanV2 is FlashLoanReceiverBaseV2, Withdrawable {
constructor(address _addressProvider) FlashLoanReceiverBaseV2(_addressProvider) public {}
/**
* #dev This function must be called only be the LENDING_POOL and takes care of repaying
* active debt positions, migrating collateral and incurring new V2 debt token debt.
*
* #param assets The array of flash loaned assets used to repay debts.
* #param amounts The array of flash loaned asset amounts used to repay debts.
* #param premiums The array of premiums incurred as additional debts.
* #param initiator The address that initiated the flash loan, unused.
* #param params The byte array containing, in this case, the arrays of aTokens and aTokenAmounts.
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{
//
// This contract now has the funds requested.
// Your logic goes here.
//
// At the end of your logic above, this contract owes
// the flashloaned amounts + premiums.
// Therefore ensure your contract has enough to repay
// these amounts.
// Approve the LendingPool contract allowance to *pull* the owed amount
for (uint i = 0; i < assets.length; i++) {
uint amountOwing = amounts[i].add(premiums[i]);
IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing);
}
for (uint i = 0; i < assets.length; i++) {
withdraw(assets[i]);
}
return true;
}
function _flashloan(address[] memory assets, uint256[] memory amounts) internal {
address receiverAddress = address(this);
address onBehalfOf = address(this);
bytes memory params = "";
uint16 referralCode = 0;
uint256[] memory modes = new uint256[](assets.length);
// 0 = no debt (flash), 1 = stable, 2 = variable
for (uint256 i = 0; i < assets.length; i++) {
modes[i] = 0;
}
LENDING_POOL.flashLoan(
receiverAddress,
assets,
amounts,
modes,
onBehalfOf,
params,
referralCode
);
}
/*
* Flash multiple assets
*/
function flashloan(address[] memory assets, uint256[] memory amounts) public onlyOwner {
_flashloan(assets, amounts);
}
/*
* Flash loan 1000000000000000000 wei (1 ether) worth of `_asset`
*/
function flashloan(address _asset) public onlyOwner {
bytes memory data = "";
uint amount = 1 ether;
address[] memory assets = new address[](1);
assets[0] = _asset;
uint256[] memory amounts = new uint256[](1);
amounts[0] = amount;
_flashloan(assets, amounts);
}
}
Withdrawable.sol (where withdraw() function comes from)
pragma solidity ^0.6.6;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
import "#openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
/**
Ensures that any contract that inherits from this contract is able to
withdraw funds that are accidentally received or stuck.
*/
contract Withdrawable is Ownable {
using SafeERC20 for ERC20;
address constant ETHER = address(0);
event LogWithdraw(
address indexed _from,
address indexed _assetAddress,
uint amount
);
/**
* #dev Withdraw asset.
* #param _assetAddress Asset to be withdrawn.
*/
function withdraw(address _assetAddress) public onlyOwner {
uint assetBalance;
if (_assetAddress == ETHER) {
address self = address(this); // workaround for a possible solidity bug
assetBalance = self.balance;
msg.sender.transfer(assetBalance);
} else {
assetBalance = ERC20(_assetAddress).balanceOf(address(this));
ERC20(_assetAddress).safeTransfer(msg.sender, assetBalance);
}
emit LogWithdraw(msg.sender, _assetAddress, assetBalance);
}
}