Added AllowedResolver security check and almost completed MakerDAO integartion.

This commit is contained in:
Sowmayjain 2018-10-25 17:57:42 +05:30
parent 4c7c79bb13
commit 2901bb85cb
4 changed files with 214 additions and 57 deletions

View File

@ -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];
}
}

View File

@ -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

View File

@ -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;

View File

@ -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 {}
}