pragmasolidity ^0.7.6;//SPDX-License-Identifier: MIT/** @title Admin contract *//// @author PaladincontractAdmin{
/** @notice (Admin) Event when the contract admin is updated */eventNewAdmin(address oldAdmin, address newAdmin);
/** @dev Admin address for this contract */addresspayableinternal admin;
modifieradminOnly() {
//allows only the admin of this contract to call the functionrequire(msg.sender== admin, '1');
_;
}
/**
* @notice Set a new Admin
* @dev Changes the address for the admin parameter
* @param _newAdmin address of the new Controller Admin
*/functionsetNewAdmin(addresspayable _newAdmin) externaladminOnly{
address _oldAdmin = admin;
admin = _newAdmin;
emit NewAdmin(_oldAdmin, _newAdmin);
}
}
Contract Source Code
File 2 of 4: ControllerProxy.sol
//██████╗ █████╗ ██╗ █████╗ ██████╗ ██╗███╗ ██╗//██╔══██╗██╔══██╗██║ ██╔══██╗██╔══██╗██║████╗ ██║//██████╔╝███████║██║ ███████║██║ ██║██║██╔██╗ ██║//██╔═══╝ ██╔══██║██║ ██╔══██║██║ ██║██║██║╚██╗██║//██║ ██║ ██║███████╗██║ ██║██████╔╝██║██║ ╚████║//╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝pragmasolidity ^0.7.6;//SPDX-License-Identifier: MITimport"./utils/Errors.sol";
import"./ControllerStorage.sol";
/** @title Paladin Controller contract *//// @author PaladincontractControllerProxyisControllerStorage{
eventNewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);
eventNewImplementation(address oldImplementation, address newImplementation);
constructor(){
admin =msg.sender;
}
/**
* @dev Proposes the address of a new Implementation (the new Controller contract)
*/functionproposeImplementation(address newPendingImplementation) publicadminOnly{
address oldPendingImplementation = pendingImplementation;
pendingImplementation = newPendingImplementation;
emit NewPendingImplementation(oldPendingImplementation, newPendingImplementation);
}
/**
* @dev Accepts the Pending Implementation as new Current Implementation
* Only callable by the Pending Implementation contract
*/functionacceptImplementation() publicreturns(bool) {
require(msg.sender== pendingImplementation || pendingImplementation ==address(0), Errors.CALLER_NOT_IMPLEMENTATION);
address oldImplementation = currentImplementation;
address oldPendingImplementation = pendingImplementation;
currentImplementation = pendingImplementation;
pendingImplementation =address(0);
emit NewImplementation(oldImplementation, currentImplementation);
emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);
returntrue;
}
/**
* @dev Delegates execution to an implementation contract.
* It returns to the external caller whatever the implementation returns
* or forwards reverts.
*/fallback() externalpayable{
// delegate all other functions to current implementation
(bool success, ) = currentImplementation.delegatecall(msg.data);
assembly {
let free_mem_ptr :=mload(0x40)
returndatacopy(free_mem_ptr, 0, returndatasize())
switch success
case0 { revert(free_mem_ptr, returndatasize()) }
default { return(free_mem_ptr, returndatasize()) }
}
}
}
Contract Source Code
File 3 of 4: ControllerStorage.sol
//██████╗ █████╗ ██╗ █████╗ ██████╗ ██╗███╗ ██╗//██╔══██╗██╔══██╗██║ ██╔══██╗██╔══██╗██║████╗ ██║//██████╔╝███████║██║ ███████║██║ ██║██║██╔██╗ ██║//██╔═══╝ ██╔══██║██║ ██╔══██║██║ ██║██║██║╚██╗██║//██║ ██║ ██║███████╗██║ ██║██████╔╝██║██║ ╚████║//╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝pragmasolidity ^0.7.6;//SPDX-License-Identifier: MITimport"./utils/Admin.sol";
/** @title Paladin Controller contract *//// @author PaladincontractControllerStorageisAdmin{
/** @notice Layout for the Proxy contract */addresspublic currentImplementation;
addresspublic pendingImplementation;
/** @notice List of current active palToken Pools */address[] public palTokens;
address[] public palPools;
mapping(address=>address) public palTokenToPalPool;
boolinternal initialized;
/** @notice Struct with current SupplyIndex for a Pool, and the block of the last update */structPoolRewardsState {
uint224 index;
uint32 blockNumber;
}
/** @notice Initial index for Rewards */uint224publicconstant initialRewardsIndex =1e36;
addresspublic rewardTokenAddress; // PAL token address to put here/** @notice State of the Rewards for each Pool */mapping(address=> PoolRewardsState) public supplyRewardState;
/** @notice Amount of reward tokens to distribute each block */mapping(address=>uint) public supplySpeeds;
/** @notice Last reward index for each Pool for each user *//** PalPool => User => Index */mapping(address=>mapping(address=>uint)) public supplierRewardIndex;
/** @notice Deposited amounts by user for each palToken (indexed by corresponding PalPool address) *//** PalPool => User => Amount */mapping(address=>mapping(address=>uint)) public supplierDeposits;
/** @notice Total amount of each palToken deposited (indexed by corresponding PalPool address) *//** PalPool => Total Amount */mapping(address=>uint) public totalSupplierDeposits;
/** @notice Ratio to distribute Borrow Rewards */mapping(address=>uint) public borrowRatios; // scaled 1e18/** @notice Ratio for each PalLoan (set at PalLoan creation) */mapping(address=>uint) public loansBorrowRatios; // scaled 1e18/** @notice Amount of reward Tokens accrued by the user, and claimable */mapping(address=>uint) public accruedRewards;
/** @notice Is Auto Borrow Rewards is activated for the PalPool */mapping(address=>bool) public autoBorrowRewards;
/** @notice Was PalLoan Borrow Rewards distributed & claimed */mapping(address=>bool) public isLoanRewardClaimed;
/** @notice Block at which Borrow Rewards Ratio where set for the PalPool (if Ratio is put back to 0, this block number is set back to 0 too) *//** So PalLoan started when no Borrow Rewards where set do not receive rewards *//** PalPool => Block Number */mapping(address=>uint) public borrowRewardsStartBlock;
/** @dev Prevent reentry in some functions */boolinternal locked;
/*
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!! ALWAYS PUT NEW STORAGE AT THE BOTTOM !!!!!!!!!!!!!!!!!!
!!!!!!!!! WE DON'T WANT COLLISION WHEN SWITCHING IMPLEMENTATIONS !!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
}
Contract Source Code
File 4 of 4: Errors.sol
//██████╗ █████╗ ██╗ █████╗ ██████╗ ██╗███╗ ██╗//██╔══██╗██╔══██╗██║ ██╔══██╗██╔══██╗██║████╗ ██║//██████╔╝███████║██║ ███████║██║ ██║██║██╔██╗ ██║//██╔═══╝ ██╔══██║██║ ██╔══██║██║ ██║██║██║╚██╗██║//██║ ██║ ██║███████╗██║ ██║██████╔╝██║██║ ╚████║//╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝pragmasolidity ^0.7.6;//SPDX-License-Identifier: MITlibraryErrors{
// Admin errorstringpublicconstant CALLER_NOT_ADMIN ='1'; // 'The caller must be the admin'stringpublicconstant CALLER_NOT_CONTROLLER ='29'; // 'The caller must be the admin or the controller'stringpublicconstant CALLER_NOT_ALLOWED_POOL ='30'; // 'The caller must be a palPool listed in the controller'stringpublicconstant CALLER_NOT_MINTER ='31';
stringpublicconstant CALLER_NOT_IMPLEMENTATION ='35'; // 'The caller must be the pending Implementation'// ERC20 type errorsstringpublicconstant FAIL_TRANSFER ='2';
stringpublicconstant FAIL_TRANSFER_FROM ='3';
stringpublicconstant BALANCE_TOO_LOW ='4';
stringpublicconstant ALLOWANCE_TOO_LOW ='5';
stringpublicconstant SELF_TRANSFER ='6';
// PalPool errorsstringpublicconstant INSUFFICIENT_CASH ='9';
stringpublicconstant INSUFFICIENT_BALANCE ='10';
stringpublicconstant FAIL_DEPOSIT ='11';
stringpublicconstant FAIL_LOAN_INITIATE ='12';
stringpublicconstant FAIL_BORROW ='13';
stringpublicconstant ZERO_BORROW ='27';
stringpublicconstant BORROW_INSUFFICIENT_FEES ='23';
stringpublicconstant LOAN_CLOSED ='14';
stringpublicconstant NOT_LOAN_OWNER ='15';
stringpublicconstant LOAN_OWNER ='16';
stringpublicconstant FAIL_LOAN_EXPAND ='17';
stringpublicconstant NOT_KILLABLE ='18';
stringpublicconstant RESERVE_FUNDS_INSUFFICIENT ='19';
stringpublicconstant FAIL_MINT ='20';
stringpublicconstant FAIL_BURN ='21';
stringpublicconstant FAIL_WITHDRAW ='24';
stringpublicconstant FAIL_CLOSE_BORROW ='25';
stringpublicconstant FAIL_KILL_BORROW ='26';
stringpublicconstant ZERO_ADDRESS ='22';
stringpublicconstant INVALID_PARAMETERS ='28';
stringpublicconstant FAIL_LOAN_DELEGATEE_CHANGE ='32';
stringpublicconstant FAIL_LOAN_TOKEN_BURN ='33';
stringpublicconstant FEES_ACCRUED_INSUFFICIENT ='34';
//Controller errorsstringpublicconstant LIST_SIZES_NOT_EQUAL ='36';
stringpublicconstant POOL_LIST_ALREADY_SET ='37';
stringpublicconstant POOL_ALREADY_LISTED ='38';
stringpublicconstant POOL_NOT_LISTED ='39';
stringpublicconstant CALLER_NOT_POOL ='40';
stringpublicconstant REWARDS_CASH_TOO_LOW ='41';
stringpublicconstant FAIL_BECOME_IMPLEMENTATION ='42';
stringpublicconstant INSUFFICIENT_DEPOSITED ='43';
stringpublicconstant NOT_CLAIMABLE ='44';
stringpublicconstant LOCKED ='45';
}