Skip to content

Commit

Permalink
Merge branch 'development' into liquidity-mining
Browse files Browse the repository at this point in the history
# Conflicts:
#	contracts/governance/Vesting/SVR.sol
#	scripts/contractInteraction/contract_interaction.py
#	scripts/contractInteraction/testnet_contracts.json
  • Loading branch information
jameshowlett977 committed May 18, 2021
2 parents 90d5157 + df0557d commit b295b8f
Show file tree
Hide file tree
Showing 117 changed files with 8,971 additions and 2,545 deletions.
3 changes: 3 additions & 0 deletions .solcover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
skipFiles: ['mockup', 'testhelpers', 'openzeppelin']
};
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
First install all the npm packages:

```
npm i
npm ci
```

And then install all the python packages using pip3:
Expand Down Expand Up @@ -63,6 +63,7 @@ To check the test coverage of JS:
```
npm run coverage
```

Note: Sometimes it might show an error "JavaScript heap out of memory", then please increase the memory allocation using:

```
Expand All @@ -74,19 +75,33 @@ If still the error persists, make sure that you closed the shell and opened anot
## Deployment on RSK testnet

1. Add account with RBTC balance to brownie

```bash
brownie accounts new rskdeployer
```

2. Add network Rsk-testnet

```bash
brownie networks add rsk testnet host=https://testnet.sovryn.app/rpc chainid=31
```

OR

```bash
brownie networks add rsk testnet host=https://public-node.testnet.rsk.co chainid=31
```

Note: If you want to work with mainnet, please use host as `wss://mainnet.sovryn.app/ws` and chainid as `30`

3. Deploy contracts locally

```bash
brownie run deploy_everything.py
```

or use an absolute path to the script

```bash
brownie run ~/Code/Sovryn-smart-contracts/scripts/deployment/deploy_everything.py
```
Expand All @@ -98,25 +113,31 @@ brownie run deploy_everything.py --network testnet
```

or use an absolute path to the script

```bash
brownie run ~/Code/Sovryn-smart-contracts/scripts/deployment/deploy_everything.py --network testnet
```

## Sovryn Swap joint testing for RSK (local)

1. Start `ganache` with

```bash
ganache-cli --gasLimit 6800000 --port 8545
```

Overriding default `brownie` port will make it connect to our local chain and keep it open.

If you changed the port in the brownie config, use that port instead.

2. Deploy contracts

```bash
brownie run deploy_everything.py
```

or use an absolute path to the script

```bash
brownie run ~/Code/Sovryn-smart-contracts/scripts/deployment/deploy_everything.py
```
Expand All @@ -130,11 +151,13 @@ brownie run ~/Code/Sovryn-smart-contracts/scripts/deployment/deploy_everything.p
6. After deployment, copy the address of the deployed `ContractRegistry` and update the `scripts/swap_test.json` accordingly.

7. Run the `swap_test.py` script to set the SovrynSwap ContractRegistry address

```bash
brownie run swap_test.py
```

or use an absolute path to the script

```bash
brownie run ~/Code/Sovryn-smart-contracts/scripts/swapTest/swap_test.py
```
Expand Down Expand Up @@ -566,6 +589,12 @@ The function which pays the reward is `PayFeeReward` from `FeesHelper.sol`.
#### 9.3 Withdraw
The protocol can withdraw SOV tokens using `sovryn.withdrawProtocolToken()` from `ProtocolSettings.sol`. This function is executable only by the owner.

## Contributing

<a href="https://github.com/DistributedCollective/Sovryn-smart-contracts/graphs/contributors">
<img src="https://contrib.rocks/image?repo=DistributedCollective/Sovryn-smart-contracts" />
</a>

## License

This project is licensed under the [Apache License, Version 2.0](LICENSE).
49 changes: 49 additions & 0 deletions contracts/connectors/loantoken/AdvancedToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,53 @@ pragma solidity 0.5.17;

import "./AdvancedTokenStorage.sol";

/**
* @title Advanced Token contract.
* @notice This contract code comes from bZx. bZx is a protocol for tokenized margin
* trading and lending https://bzx.network similar to the dYdX protocol.
*
* AdvancedToken implements standard ERC-20 approval, mint and burn token functionality.
* Logic (AdvancedToken) is kept aside from storage (AdvancedTokenStorage).
*
* For example, LoanTokenLogicDai contract uses AdvancedToken::_mint() to mint
* its Loan Dai iTokens.
* */
contract AdvancedToken is AdvancedTokenStorage {
using SafeMath for uint256;

/**
* @notice Set an amount as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*
* @param _spender The account address that will be able to spend the tokens.
* @param _value The amount of tokens allowed to spend.
* */
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}

/**
* @notice The iToken minting process. Meant to issue Loan iTokens.
* Lenders are able to open an iToken position, by minting them.
* This function is called by LoanTokenLogicStandard::_mintToken
* @param _to The recipient of the minted tTokens.
* @param _tokenAmount The amount of iTokens to be minted.
* @param _assetAmount The amount of lended tokens (asset to lend).
* @param _price The price of the lended tokens.
* @return The updated balance of the recipient.
* */
function _mint(
address _to,
uint256 _tokenAmount,
Expand All @@ -35,6 +73,16 @@ contract AdvancedToken is AdvancedTokenStorage {
return _balance;
}

/**
* @notice The iToken burning process. Meant to destroy Loan iTokens.
* Lenders are able to close an iToken position, by burning them.
* This function is called by LoanTokenLogicStandard::_burnToken
* @param _who The owner of the iTokens to burn.
* @param _tokenAmount The amount of iTokens to burn.
* @param _assetAmount The amount of lended tokens.
* @param _price The price of the lended tokens.
* @return The updated balance of the iTokens owner.
* */
function _burn(
address _who,
uint256 _tokenAmount,
Expand All @@ -47,6 +95,7 @@ contract AdvancedToken is AdvancedTokenStorage {

// a rounding error may leave dust behind, so we clear this out
if (_balance <= 10) {
// We can't leave such small balance quantities.
_tokenAmount = _tokenAmount.add(_balance);
_balance = 0;
}
Expand Down
37 changes: 37 additions & 0 deletions contracts/connectors/loantoken/AdvancedTokenStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,68 @@ pragma solidity 0.5.17;

import "./LoanTokenBase.sol";

/**
* @title Advanced Token Storage contract.
* @notice This contract code comes from bZx. bZx is a protocol for tokenized
* margin trading and lending https://bzx.network similar to the dYdX protocol.
*
* AdvancedTokenStorage implements standard ERC-20 getters functionality:
* totalSupply, balanceOf, allowance and some events.
* iToken logic is divided into several contracts AdvancedToken,
* AdvancedTokenStorage and LoanTokenBase.
* */
contract AdvancedTokenStorage is LoanTokenBase {
using SafeMath for uint256;

/* Events */

/// topic: 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
event Transfer(address indexed from, address indexed to, uint256 value);

/// topic: 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925
event Approval(address indexed owner, address indexed spender, uint256 value);

/// topic: 0xb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb
event Mint(address indexed minter, uint256 tokenAmount, uint256 assetAmount, uint256 price);

/// topic: 0x743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b4644
event Burn(address indexed burner, uint256 tokenAmount, uint256 assetAmount, uint256 price);

event FlashBorrow(address borrower, address target, address loanToken, uint256 loanAmount);

/* Storage */

mapping(address => uint256) internal balances;
mapping(address => mapping(address => uint256)) internal allowed;
uint256 internal totalSupply_;

/* Functions */

/**
* @notice Get the total supply of iTokens.
* @return The total number of iTokens in existence as of now.
* */
function totalSupply() public view returns (uint256) {
return totalSupply_;
}

/**
* @notice Get the amount of iTokens owned by an account.
* @param _owner The account owner of the iTokens.
* @return The number of iTokens an account owns.
* */
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}

/**
* @notice Get the amount of iTokens allowed to be spent by a
* given account on behalf of the owner.
* @param _owner The account owner of the iTokens.
* @param _spender The account allowed to send the iTokens.
* @return The number of iTokens an account is allowing the spender
* to send on its behalf.
* */
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
Expand Down
67 changes: 64 additions & 3 deletions contracts/connectors/loantoken/LoanToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,42 @@ pragma solidity 0.5.17;

import "./AdvancedTokenStorage.sol";

/**
* @title Loan Token contract.
* @notice This contract code comes from bZx. bZx is a protocol for tokenized
* margin trading and lending https://bzx.network similar to the dYdX protocol.
*
* A loan token (iToken) is created as a proxy to an upgradable token contract.
*
* Examples of loan tokens on Sovryn are iRBTC, iDOC, iUSDT, iBPro,
* iSOV (near future).
*
* Lenders receive iTokens that collect interest from the lending pool
* which they can redeem by withdrawing them. The i in iToken stands for interest.
*
* Do not confuse iTokens with underlying tokens. iDOC is an iToken (loan token)
* whilest DOC is the underlying token (currency).
*
* @dev TODO: can I change this proxy to EIP-1822 proxy standard, please.
* https://eips.ethereum.org/EIPS/eip-1822. It's really hard to work with this.
* */
contract LoanToken is AdvancedTokenStorage {
// It is important to maintain the variables order so the delegate calls can access sovrynContractAddress and wrbtcTokenAddress
/// @dev It is important to maintain the variables order so the delegate
/// calls can access sovrynContractAddress and wrbtcTokenAddress
address public sovrynContractAddress;
address public wrbtcTokenAddress;
address internal target_;
address public admin;

/**
* @notice Deploy loan token proxy.
* Sets ERC20 parameters of the token.
*
* @param _newOwner The address of the new owner.
* @param _newTarget The address of the new target contract instance.
* @param _sovrynContractAddress The address of the new sovrynContract instance.
* @param _wrbtcTokenAddress The address of the new wrBTC instance.
* */
constructor(
address _newOwner,
address _newTarget,
Expand All @@ -26,6 +55,11 @@ contract LoanToken is AdvancedTokenStorage {
_setWrbtcTokenAddress(_wrbtcTokenAddress);
}

/**
* @notice Fallback function performs a delegate call
* to the actual implementation address is pointing this proxy.
* Returns whatever the implementation call returns.
* */
function() external payable {
if (gasleft() <= 2300) {
return;
Expand All @@ -48,26 +82,53 @@ contract LoanToken is AdvancedTokenStorage {
}
}

/**
* @notice Public owner setter for target address.
* @dev Calls internal setter.
* @param _newTarget The address of the new target contract instance.
* */
function setTarget(address _newTarget) public onlyOwner {
_setTarget(_newTarget);
}

/**
* @notice Internal setter for target address.
* @param _newTarget The address of the new target contract instance.
* */
function _setTarget(address _newTarget) internal {
require(Address.isContract(_newTarget), "target not a contract");
target_ = _newTarget;
}

/**
* @notice Internal setter for sovrynContract address.
* @param _sovrynContractAddress The address of the new sovrynContract instance.
* */
function _setSovrynContractAddress(address _sovrynContractAddress) internal {
require(Address.isContract(_sovrynContractAddress), "sovryn not a contract");
sovrynContractAddress = _sovrynContractAddress;
}

/**
* @notice Internal setter for wrBTC address.
* @param _wrbtcTokenAddress The address of the new wrBTC instance.
* */
function _setWrbtcTokenAddress(address _wrbtcTokenAddress) internal {
require(Address.isContract(_wrbtcTokenAddress), "wrbtc not a contract");
wrbtcTokenAddress = _wrbtcTokenAddress;
}

//@todo add check for double init, idk but init usually can be called only once.
/**
* @notice Public owner cloner for pointed loan token.
* Sets ERC20 parameters of the token.
*
* @dev TODO: add check for double init.
* idk but init usually can be called only once.
*
* @param _loanTokenAddress The address of the pointed loan token instance.
* @param _name The ERC20 token name.
* @param _symbol The ERC20 token symbol.
* */
function initialize(
address _loanTokenAddress,
string memory _name,
Expand All @@ -79,6 +140,6 @@ contract LoanToken is AdvancedTokenStorage {
symbol = _symbol;
decimals = IERC20(loanTokenAddress).decimals();

initialPrice = 10**18; // starting price of 1
initialPrice = 10**18; /// starting price of 1
}
}
Loading

0 comments on commit b295b8f

Please sign in to comment.