Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AIP-6 #193

Closed
wants to merge 28 commits into from
Closed

AIP-6 #193

Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c0b5739
Bump lodash from 4.17.13 to 4.17.19 (#154)
dependabot[bot] Dec 23, 2020
3f21570
Bump tree-kill from 1.2.0 to 1.2.2 (#167)
dependabot[bot] Dec 23, 2020
c3bacb1
migrate to hardhat
thegostep Sep 28, 2020
9437698
add formatting
thegostep Dec 23, 2020
489ac6a
Merge pull request #176 from ampleforth/hardhat-refactor
thegostep Jan 8, 2021
3442040
Merge pull request #177 from ampleforth/formatting
thegostep Jan 8, 2021
aa041bc
erc-20 interface update (#180)
aalavandhan Jan 11, 2021
abcc0e5
Gas optimization on erc-20 (#182)
aalavandhan Jan 12, 2021
09be39b
updated function access modifiers fixes #185 #183 (#186)
aalavandhan Jan 12, 2021
4aba740
Add getGlobalAmpleforthEpochAndAMPLSupply (#189)
aalavandhan Jan 15, 2021
dd0465a
Public Contract interfaces (#190)
aalavandhan Jan 21, 2021
54d7184
Fixed solidity version on interface files
aalavandhan Jan 21, 2021
6dde1cc
UNDO: Fixed solidity version on interface files
aalavandhan Jan 21, 2021
d646687
Removing solidity ersion numbers in the interface definitions
aalavandhan Jan 21, 2021
dac98a1
adding truffle file back (#194)
aalavandhan Feb 3, 2021
ed86918
transferAll and transferAllFrom (#187)
aalavandhan Feb 3, 2021
1f43051
Upgrading token compiler version (#195)
aalavandhan Feb 5, 2021
404bd9e
fixed #178 (#181)
aalavandhan Feb 5, 2021
97c89a1
using solditiy max function to get the max value (#196)
aalavandhan Feb 15, 2021
1a3245b
Replacing if statement with ternary operator (#198)
aalavandhan Feb 15, 2021
57e322f
bumping up solidity to version 0.7.x (#197)
aalavandhan Feb 16, 2021
4d71b55
fixed flaky test (#200)
aalavandhan Feb 16, 2021
212d341
Revert "gas optimization" (#199)
aalavandhan Feb 16, 2021
35b6cbd
Add inline documentation to document that Orchestrator will revert if…
tedwu13 Feb 18, 2021
4aefc98
fixed variable visiblity (#202)
aalavandhan Feb 18, 2021
7bd815f
verification script (#201)
aalavandhan Feb 18, 2021
52ca7be
added coinmarket cap key for usd gas price (#205)
aalavandhan Feb 19, 2021
213cfb7
Replace custom external call with native solidity .call (#204)
tedwu13 Feb 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .coveralls.yml

This file was deleted.

67 changes: 0 additions & 67 deletions .eslintrc.js

This file was deleted.

7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,10 @@ scDebugLog
coverage.json
coverage/
coverageEnv/

node_modules

#Buidler files
cache
artifacts
.openzeppelin
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12
20 changes: 20 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"semi": false,
"trailingComma": "all",
"singleQuote": true,
"bracketSpacing": true,
"printWidth": 80,
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 100,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false,
"explicitTypes": "always"
}
}
]
}
16 changes: 2 additions & 14 deletions .solcover.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
const _require = require('app-root-path').require;
const config = _require('/truffle.js').networks.testrpcCoverage;

module.exports = {
host: config.host,
network_id: config.network_id,
port: config.port,
gas: config.gas,
gasPrice: config.gasPrice,
norpc: true,
testCommand: 'npx truffle test ./test/unit/*.js',
compileCommand: 'npx truffle compile',
skipFiles: ['mocks'],
copyPackages: ['openzeppelin-eth'],
};
skipFiles: ['mocks'],
}
14 changes: 7 additions & 7 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"extends": "default",
"rules": {
"not-rely-on-time": [false],
"no-simple-event-func-name": [false],
"indent": ["warn", 4],
"max-line-length": ["error", 100]
}
"extends": "solhint:default",
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"not-rely-on-time": "off",
"max-line-length": ["error", 100]
}
}
14 changes: 5 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@ dist: trusty
sudo: required
language: node_js
node_js:
- "8"
- '12'
cache:
directories:
- node_modules
- $(npm config get prefix)/bin/ganache-cli
before_install:
- npm install -g [email protected] # Locking npm to 6.4.1
- npm install -g npx
script:
- ./scripts/setup-ci.sh
- npm run lint
- npm run test
- npm run coverage
- yarn format
- yarn lint
- yarn test
- yarn coverage
after_success:
- cat coverage/lcov.info | npx coveralls
notifications:
Expand Down
35 changes: 17 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Ampleforth (code name uFragments) is a decentralized elastic supply protocol. It
This repository is a collection of [smart contracts](http://ampleforth.org/docs) that implement the Ampleforth protocol on the Ethereum blockchain.

The official mainnet addresses are:

- ERC-20 Token: [0xD46bA6D942050d489DBd938a2C909A5d5039A161](https://etherscan.io/token/0xd46ba6d942050d489dbd938a2c909a5d5039a161)
- Supply Policy: [0x1B228a749077b8e307C5856cE62Ef35d96Dca2ea](https://etherscan.io/address/0x1b228a749077b8e307c5856ce62ef35d96dca2ea)
- Orchestrator: [0x6fb00a180781e75f87e2b690af0196baa77c7e7c](https://etherscan.io/address/0x6fb00a180781e75f87e2b690af0196baa77c7e7c)
Expand All @@ -21,32 +22,24 @@ The official mainnet addresses are:
- [Contribute](#contribute)
- [License](#license)


## Install

```bash
# Install project dependencies
npm install

# Install ethereum local blockchain(s) and associated dependencies
npx setup-local-chains
yarn
```

## Testing

``` bash
# You can use the following command to start a local blockchain instance
npx start-chain [ganacheUnitTest|gethUnitTest]

# Run all unit tests
npm test

# Run unit tests in isolation
npx truffle --network ganacheUnitTest test test/unit/uFragments.js
```bash
# Run all unit tests (compatible with node v12+)
yarn test
```

## Testnets

There is a testnet deployment on Rinkeby. It rebases hourly using real market data.

- ERC-20 Token: [0x027dbcA046ca156De9622cD1e2D907d375e53aa7](https://rinkeby.etherscan.io/token/0x027dbcA046ca156De9622cD1e2D907d375e53aa7)
- Supply Policy: [0x1D2771AFC894107c4edc072e3bd15Cb7F1BCC007](https://rinkeby.etherscan.io/address/0x1D2771AFC894107c4edc072e3bd15Cb7F1BCC007)
- Orchestrator: [0xF473604Be74A69a6bB4ebED33A91a291f6C5b5DE](https://rinkeby.etherscan.io/address/0xF473604Be74A69a6bB4ebED33A91a291f6C5b5DE)
Expand All @@ -59,12 +52,18 @@ To report bugs within this package, create an issue in this repository.
For security issues, please contact [email protected].
When submitting code ensure that it is free of lint errors and has 100% test coverage.

``` bash
```bash
# Lint code
npm run lint
yarn lint

# Format code
yarn format

# Run solidity coverage report (compatible with node v12)
yarn coverage

# View code coverage
npm run coverage
# Run solidity gas usage report
yarn profile
```

## License
Expand Down
68 changes: 21 additions & 47 deletions contracts/Orchestrator.sol
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
pragma solidity 0.4.24;
pragma solidity 0.7.6;

import "openzeppelin-eth/contracts/ownership/Ownable.sol";
import "./_external/Ownable.sol";

import "./UFragmentsPolicy.sol";


/**
* @title Orchestrator
* @notice The orchestrator is the main entry point for rebase operations. It coordinates the policy
* actions with external consumers.
*/
contract Orchestrator is Ownable {

struct Transaction {
bool enabled;
address destination;
bytes data;
}

event TransactionFailed(address indexed destination, uint index, bytes data);
event TransactionFailed(address indexed destination, uint256 index, bytes data);

// Stable ordering is not guaranteed.
Transaction[] public transactions;
Expand All @@ -38,21 +36,18 @@ contract Orchestrator is Ownable {
* The Orchestrator calls rebase on the policy and notifies downstream applications.
* Contracts are guarded from calling, to avoid flash loan attacks on liquidity
* providers.
* If a transaction in the transaction list reverts, it is swallowed and the remaining
* transactions are executed.
* If a transaction in the transaction list fails, Orchestrator will stop execution
* and revert to prevent a gas underprice attack.
*/
function rebase()
external
{
require(msg.sender == tx.origin); // solhint-disable-line avoid-tx-origin
function rebase() external {
require(msg.sender == tx.origin); // solhint-disable-line avoid-tx-origin

policy.rebase();

for (uint i = 0; i < transactions.length; i++) {
for (uint256 i = 0; i < transactions.length; i++) {
Transaction storage t = transactions[i];
if (t.enabled) {
bool result =
externalCall(t.destination, t.data);
bool result = externalCall(t.destination, t.data);
if (!result) {
emit TransactionFailed(t.destination, i, t.data);
revert("Transaction Failed");
Expand All @@ -66,54 +61,37 @@ contract Orchestrator is Ownable {
* @param destination Address of contract destination
* @param data Transaction data payload
*/
function addTransaction(address destination, bytes data)
external
onlyOwner
{
transactions.push(Transaction({
enabled: true,
destination: destination,
data: data
}));
function addTransaction(address destination, bytes memory data) external onlyOwner {
transactions.push(Transaction({enabled: true, destination: destination, data: data}));
}

/**
* @param index Index of transaction to remove.
* Transaction ordering may have changed since adding.
*/
function removeTransaction(uint index)
external
onlyOwner
{
function removeTransaction(uint256 index) external onlyOwner {
require(index < transactions.length, "index out of bounds");

if (index < transactions.length - 1) {
transactions[index] = transactions[transactions.length - 1];
}

transactions.length--;
transactions.pop();
}

/**
* @param index Index of transaction. Transaction ordering may have changed since adding.
* @param enabled True for enabled, false for disabled.
*/
function setTransactionEnabled(uint index, bool enabled)
external
onlyOwner
{
function setTransactionEnabled(uint256 index, bool enabled) external onlyOwner {
require(index < transactions.length, "index must be in range of stored tx list");
transactions[index].enabled = enabled;
}

/**
* @return Number of transactions, both enabled and disabled, in transactions list.
*/
function transactionsSize()
external
view
returns (uint256)
{
function transactionsSize() external view returns (uint256) {
return transactions.length;
}

Expand All @@ -123,12 +101,10 @@ contract Orchestrator is Ownable {
* @param data The encoded data payload.
* @return True on success
*/
function externalCall(address destination, bytes data)
internal
returns (bool)
{
function externalCall(address destination, bytes memory data) internal returns (bool) {
aalavandhan marked this conversation as resolved.
Show resolved Hide resolved
bool result;
assembly { // solhint-disable-line no-inline-assembly
assembly {
// solhint-disable-line no-inline-assembly
// "Allocate" memory for output
// (0x40 is where "free memory" pointer is stored by convention)
let outputAddress := mload(0x40)
Expand All @@ -141,15 +117,13 @@ contract Orchestrator is Ownable {
// It includes callGas (700) + callVeryLow (3, to pay for SUB)
// + callValueTransferGas (9000) + callNewAccountGas
// (25000, in case the destination address does not exist and needs creating)
sub(gas, 34710),


sub(gas(), 34710),
destination,
0, // transfer value in wei
dataAddress,
mload(data), // Size of the input, in bytes. Stored in position 0 of the array.
mload(data), // Size of the input, in bytes. Stored in position 0 of the array.
outputAddress,
0 // Output is ignored, therefore the output size is zero
0 // Output is ignored, therefore the output size is zero
)
}
return result;
Expand Down
Loading