mirror of
https://github.com/Instadapp/InstaContract.git
synced 2024-07-29 22:47:45 +00:00
Added AllowedResolver security check and almost completed MakerDAO integartion.
This commit is contained in:
parent
4c7c79bb13
commit
2901bb85cb
|
@ -1,8 +1,8 @@
|
|||
// Implement the proper governance mechanism to update the admin address like admin have rights to upgrade anything but not just "admin". Governance will be used to set admin address.
|
||||
// Or keep AllowedResolver also in MoatAddress contract
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract AddressRegistry {
|
||||
|
||||
event AddressChanged(string name, address target);
|
||||
|
@ -30,4 +30,19 @@ contract AddressRegistry {
|
|||
require(addr != address(0), "Not a valid address.");
|
||||
}
|
||||
|
||||
// Contract Address >> Asset Owner Address >> Bool
|
||||
mapping(address => mapping(address => bool)) allowedResolver;
|
||||
|
||||
function allowContract() public {
|
||||
allowedResolver[getAddr("resolver")][msg.sender] = true;
|
||||
}
|
||||
|
||||
function disallowContract() public {
|
||||
allowedResolver[getAddr("resolver")][msg.sender] = false;
|
||||
}
|
||||
|
||||
function isApprovedResolver(address user) public view returns(bool) {
|
||||
return allowedResolver[getAddr("resolver")][user];
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
// Allow ERC20 deposits
|
||||
// withdraw the extra assets other than global balance (in case anyone donated for free) and then no need for seperate brokerage calculation
|
||||
// how the balance of tokens with less than 18 decimals are stored
|
||||
// update the balance along with "transferAssets" functions and also check the for onlyAllowedResolver
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
interface AddressRegistry {
|
||||
function getAddr(string name) external returns(address);
|
||||
function isApprovedResolver(address user) external returns(bool);
|
||||
}
|
||||
|
||||
interface token {
|
||||
|
@ -16,6 +19,8 @@ interface token {
|
|||
contract Registry {
|
||||
|
||||
address public registryAddress;
|
||||
AddressRegistry aRegistry = AddressRegistry(registryAddress);
|
||||
|
||||
modifier onlyAdmin() {
|
||||
require(
|
||||
msg.sender == getAddress("admin"),
|
||||
|
@ -24,8 +29,15 @@ contract Registry {
|
|||
_;
|
||||
}
|
||||
|
||||
modifier onlyAllowedResolver(address user) {
|
||||
require(
|
||||
aRegistry.isApprovedResolver(user),
|
||||
"Permission Denied"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
function getAddress(string name) internal view returns(address addr) {
|
||||
AddressRegistry aRegistry = AddressRegistry(registryAddress);
|
||||
addr = aRegistry.getAddr(name);
|
||||
require(addr != address(0), "Invalid Address");
|
||||
}
|
||||
|
@ -33,41 +45,7 @@ contract Registry {
|
|||
}
|
||||
|
||||
|
||||
contract AllowedResolver is Registry {
|
||||
|
||||
// Contract Address >> Asset Owner Address >> Bool
|
||||
mapping(address => mapping(address => bool)) allowed;
|
||||
bool public enabled;
|
||||
modifier onlyAllowedResolver() {
|
||||
require(
|
||||
allowed[getAddress("resolver")][msg.sender],
|
||||
"Permission Denied"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
// only the contracts allowed for asset owners can withdraw assets and update balance on behalf
|
||||
function allowContract() public {
|
||||
allowed[getAddress("resolver")][msg.sender] = true;
|
||||
}
|
||||
|
||||
function disallowContract() public {
|
||||
allowed[getAddress("resolver")][msg.sender] = false;
|
||||
}
|
||||
|
||||
// enableAC & disableAC will completely stop the withdrawal of assets on behalf (additional security check)
|
||||
function enableAC() public onlyAdmin {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
function disableAC() public onlyAdmin {
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
contract AssetDB is AllowedResolver {
|
||||
contract AssetDB is Registry {
|
||||
|
||||
// AssetOwner >> TokenAddress >> Balance (as per respective decimals)
|
||||
mapping(address => mapping(address => uint)) balances;
|
||||
|
@ -101,7 +79,7 @@ contract AssetDB is AllowedResolver {
|
|||
uint amt,
|
||||
bool add,
|
||||
address target
|
||||
) public onlyAllowedResolver
|
||||
) public onlyAllowedResolver(target)
|
||||
{
|
||||
if (add) {
|
||||
balances[target][tokenAddr] += amt;
|
||||
|
@ -110,19 +88,19 @@ contract AssetDB is AllowedResolver {
|
|||
}
|
||||
}
|
||||
|
||||
function transferAssets(
|
||||
address tokenAddress,
|
||||
uint amount,
|
||||
address sendTo
|
||||
) public onlyAllowedResolver
|
||||
{
|
||||
if (tokenAddress == eth) {
|
||||
sendTo.transfer(amount);
|
||||
} else {
|
||||
token tokenFunctions = token(tokenAddress);
|
||||
tokenFunctions.transfer(sendTo, amount);
|
||||
}
|
||||
}
|
||||
// function transferAssets(
|
||||
// address tokenAddress,
|
||||
// uint amount,
|
||||
// address sendTo
|
||||
// ) public onlyAllowedResolver
|
||||
// {
|
||||
// if (tokenAddress == eth) {
|
||||
// sendTo.transfer(amount);
|
||||
// } else {
|
||||
// token tokenFunctions = token(tokenAddress);
|
||||
// tokenFunctions.transfer(sendTo, amount);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
@ -131,7 +109,6 @@ contract MoatAsset is AssetDB {
|
|||
|
||||
constructor(address rAddr) public {
|
||||
registryAddress = rAddr;
|
||||
enableAC();
|
||||
}
|
||||
|
||||
// received ether directly from protocols like Kyber Network
|
||||
|
|
|
@ -45,7 +45,7 @@ contract Registry {
|
|||
}
|
||||
|
||||
|
||||
contract KyberSwap is Registry {
|
||||
contract Trade is Registry {
|
||||
|
||||
event Swapped(address src, uint srcAmt, address dest, uint destAmt);
|
||||
|
||||
|
@ -86,7 +86,7 @@ contract KyberSwap is Registry {
|
|||
}
|
||||
|
||||
|
||||
contract KyberInit is KyberSwap {
|
||||
contract MoatKyber is Trade {
|
||||
|
||||
constructor(address rAddr) public {
|
||||
registryAddress = rAddr;
|
||||
|
|
|
@ -1,3 +1,168 @@
|
|||
// MakerDAO integration
|
||||
// https://github.com/cryptoPay-ETHSF/SmartContract/blob/master/CryptoPayKovan.sol
|
||||
// this contract will be the owner of all the CDPs, upgrading this means all the data need to be migrated
|
||||
// transfer or get back ownership of CDP
|
||||
// this contract will be the owner of all the CDPs, upgrading this means all the data need to be migrated
|
||||
// factor the WETH to PETH conversion rate
|
||||
// run an event after changing the CDP ownership
|
||||
// implement repay loan function
|
||||
// implement allowed functionalities like MoatAsset as CDPs are owned by this contract
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
|
||||
interface token {
|
||||
function transfer(address receiver, uint amount) external returns(bool);
|
||||
function balanceOf(address who) external returns(uint256);
|
||||
function approve(address spender, uint256 value) external returns (bool);
|
||||
function transferFrom(address from, address to, uint amt) external returns (bool);
|
||||
}
|
||||
|
||||
interface AddressRegistry {
|
||||
function getAddr(string name) external returns(address);
|
||||
function isApprovedResolver(address user) external returns(bool);
|
||||
}
|
||||
|
||||
interface MakerCDP {
|
||||
function open() external returns (bytes32 cup);
|
||||
function join(uint wad) external; // Join PETH
|
||||
function exit(uint wad) external; // Exit PETH
|
||||
function give(bytes32 cup, address guy) external;
|
||||
function lock(bytes32 cup, uint wad) external;
|
||||
function free(bytes32 cup, uint wad) external;
|
||||
function draw(bytes32 cup, uint wad) external;
|
||||
function wipe(bytes32 cup, uint wad) external;
|
||||
function shut(bytes32 cup) external;
|
||||
function bite(bytes32 cup) external;
|
||||
}
|
||||
|
||||
interface WETHFace {
|
||||
function deposit() external payable;
|
||||
function withdraw(uint wad) external;
|
||||
}
|
||||
|
||||
|
||||
contract Registry {
|
||||
|
||||
address public registryAddress;
|
||||
AddressRegistry aRegistry = AddressRegistry(registryAddress);
|
||||
|
||||
modifier onlyAdmin() {
|
||||
require(
|
||||
msg.sender == getAddress("admin"),
|
||||
"Permission Denied"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
function getAddress(string name) internal view returns(address addr) {
|
||||
addr = aRegistry.getAddr(name);
|
||||
require(addr != address(0), "Invalid Address");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
contract GlobalVar is Registry {
|
||||
|
||||
address public WETH = 0xd0a1e359811322d97991e03f863a0c30c2cf029c;
|
||||
address public PETH = 0xf4d791139ce033ad35db2b2201435fad668b1b64;
|
||||
address public MKR = 0xaaf64bfcc32d0f15873a02163e7e500671a4ffcd;
|
||||
address public DAI = 0xc4375b7de8af5a38a93548eb8453a498222c4ff2;
|
||||
|
||||
address public CDPAddr = 0xa71937147b55Deb8a530C7229C442Fd3F31b7db2;
|
||||
MakerCDP DAILoanMaster = MakerCDP(CDPAddr);
|
||||
|
||||
mapping (address => bytes32) public borrowerCDPs; // borrower >>> CDP Bytes
|
||||
|
||||
}
|
||||
|
||||
|
||||
contract BorrowTasks is GlobalVar {
|
||||
|
||||
function openCDP() internal returns (bytes32) {
|
||||
return DAILoanMaster.open();
|
||||
}
|
||||
|
||||
function ETH_WETH(uint weiAmt) internal {
|
||||
WETHFace wethFunction = WETHFace(WETH);
|
||||
wethFunction.deposit.value(weiAmt)();
|
||||
}
|
||||
|
||||
function WETH_PETH(uint weiAmt) internal {
|
||||
DAILoanMaster.join(weiAmt);
|
||||
}
|
||||
|
||||
function PETH_CDP(address borrower, uint weiAmt) internal {
|
||||
DAILoanMaster.lock(borrowerCDPs[borrower], weiAmt);
|
||||
}
|
||||
|
||||
function transferCDP(address nextOwner) public {
|
||||
require(nextOwner != 0, "Invalid Address.");
|
||||
DAILoanMaster.give(borrowerCDPs[msg.sender], nextOwner);
|
||||
}
|
||||
|
||||
function ApproveERC20() public {
|
||||
token WETHtkn = token(WETH);
|
||||
WETHtkn.approve(CDPAddr, 2**256 - 1);
|
||||
token PETHtkn = token(PETH);
|
||||
PETHtkn.approve(CDPAddr, 2**256 - 1);
|
||||
token MKRtkn = token(MKR);
|
||||
MKRtkn.approve(CDPAddr, 2**256 - 1);
|
||||
token DAItkn = token(DAI);
|
||||
DAItkn.approve(CDPAddr, 2**256 - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
contract Borrow is BorrowTasks {
|
||||
|
||||
modifier securedResolver(address borrower) {
|
||||
if (borrower != msg.sender) {
|
||||
require(
|
||||
msg.sender == getAddress("resolver"),
|
||||
"Message Sender is not MoatResolver."
|
||||
);
|
||||
require(
|
||||
aRegistry.isApprovedResolver(borrower),
|
||||
"MoatResolver is not approved by CDP user."
|
||||
);
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
function borrowLoan(
|
||||
address borrower,
|
||||
uint lockETH,
|
||||
uint loanDAI
|
||||
) public securedResolver(borrower) {
|
||||
|
||||
if (borrowerCDPs[borrower] == 0x0000000000000000000000000000000000000000000000000000000000000000) {
|
||||
borrowerCDPs[borrower] = openCDP();
|
||||
}
|
||||
|
||||
if (lockETH != 0) {
|
||||
ETH_WETH(lockETH);
|
||||
WETH_PETH(lockETH - lockETH/1000);
|
||||
PETH_CDP(borrower, lockETH - lockETH/1000);
|
||||
// event for locking ETH
|
||||
}
|
||||
|
||||
if (loanDAI != 0) {
|
||||
DAILoanMaster.draw(borrowerCDPs[borrower], loanDAI);
|
||||
token tokenFunctions = token(DAI);
|
||||
tokenFunctions.transfer(getAddress("asset"), loanDAI);
|
||||
// event for drawing DAI
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
contract MoatMaker is Borrow {
|
||||
|
||||
constructor() public {
|
||||
ApproveERC20();
|
||||
}
|
||||
|
||||
function () public payable {}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user