Skip to content

Commit

Permalink
feat: Brownie Tutorial Lesson 25
Browse files Browse the repository at this point in the history
  • Loading branch information
zcor committed Nov 29, 2021
1 parent 6c0b3cf commit a4639ef
Show file tree
Hide file tree
Showing 39 changed files with 2,363 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ Companion repository for Curve's [Brownie Tutorial](https://www.youtube.com/play
* [Lesson 21: Deployment](/lesson-21-deployment)
* [Lesson 22: Unit Testing I](/lesson-22-unit-testing-i)
* [Lesson 23: Reverts](/lesson-23-reverts)
* [Lesson 24: Interactive Debugging](/lesson-24-interactive)
* [Lesson 24: Interactive Debugging I](/lesson-24-interactive-i)
* [Lesson 25: Interactive Debugging II](/lesson-25-interactive-ii)

## In the Oven
* React
Expand Down
19 changes: 19 additions & 0 deletions lesson-24-interactive-i/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Interactive Debugging

## [🎥 Video 24: Interactive Debugging I 🎬](https://youtu.be/zHQ4cjzIg1Y)

The Brownie interactive flag allows for extra convenience with debugging and development of smart contracts. When a test fails, it drops you right on a console at the exact point of failure with access to all relevant variables.


## INTERACTIVE DEBUGGING MODE
When a test fails, open a console and interact with any variables at the point of failure.

> brownie test --interactive
> brownie test -I


## STRATEGY EXCLUSION
Pass the exclude flag to filter an object, iterable or callable

> strategy(strategy_type, excludes=...)

116 changes: 116 additions & 0 deletions lesson-24-interactive-i/diff.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
diff -r ../lesson-23-reverts/margarita/contracts/Stake.vy margarita/contracts/Stake.vy
21a22,25
>
> interface Curve2PoolUnderlying:
> def add_liquidity(amountsUnderlying: uint256[2], min_mint_amount: uint256, use_underlying: bool): nonpayable
> def remove_liquidity(_amountUnderlying: uint256, min_amounts: uint256[2]): nonpayable
22a27,35
> interface Curve3PoolUnderlying:
> def add_liquidity(amountsUnderlying: uint256[3], min_mint_amount: uint256, use_underlying: bool): nonpayable
> def remove_liquidity(_amountUnderlying: uint256, min_amounts: uint256[3]): nonpayable
>
> interface Curve4PoolUnderlying:
> def add_liquidity(amountsUnderlying: uint256[4], min_mint_amount: uint256, use_underlying: bool): nonpayable
> def remove_liquidity(_amount: uint256, min_amounts: uint256[4]): nonpayable
>
>
30a44
> def get_underlying_coins(_pool: address) -> address[8]: view
47a62,68
> @internal
> def _load_coins(pool_addr: address, use_underlying: bool) -> address[8]:
> if use_underlying == True:
> return self.registry.get_underlying_coins(pool_addr)
> else:
> return self.registry.get_coins(pool_addr)
>
49c70
< def _get_coin_index(coin_addr: address, pool_addr: address) -> int256[2]:
---
> def _get_coin_index(coin_addr: address, pool_addr: address, use_underlying: bool) -> int256[2]:
55c76
< coins: address[8] = self.registry.get_coins(pool_addr)
---
> coins: address[8] = self._load_coins(pool_addr, use_underlying)
69c90,93
< def _add_liquidity(coin_addr: address, pool_addr: address):
---
> def _add_liquidity(
> coin_addr: address,
> pool_addr: address,
> use_underlying: bool):
79c103
< coin_index: int256[2] = self._get_coin_index(coin_addr, pool_addr)
---
> coin_index: int256[2] = self._get_coin_index(coin_addr, pool_addr, use_underlying)
85c109,113
< Curve2Pool(pool_addr).add_liquidity(liq_arr, 0)
---
> if use_underlying:
> Curve2PoolUnderlying(pool_addr).add_liquidity(liq_arr, 0, True)
> else:
> Curve2Pool(pool_addr).add_liquidity(liq_arr, 0)
>
90c118,123
< Curve3Pool(pool_addr).add_liquidity(liq_arr, 0)
---
> if use_underlying:
> Curve3PoolUnderlying(pool_addr).add_liquidity(liq_arr, 0, True)
> else:
> Curve3Pool(pool_addr).add_liquidity(liq_arr, 0)
>
>
94c127,131
< Curve4Pool(pool_addr).add_liquidity(liq_arr, 0)
---
> if use_underlying:
> Curve4PoolUnderlying(pool_addr).add_liquidity(liq_arr, 0, True)
> else:
> Curve4Pool(pool_addr).add_liquidity(liq_arr, 0)
>
123c160,163
< if self.registry.is_meta(pool_addr):
---
> if coin_addr in self.registry.get_coins(pool_addr):
> self._add_liquidity(coin_addr, pool_addr, False)
>
> elif self.registry.is_meta(pool_addr):
126,127c166,169
< self._add_liquidity(coin_addr, metapool)
< self._add_liquidity(metapool_lp, pool_addr)
---
> self._add_liquidity(coin_addr, metapool, False)
> self._add_liquidity(metapool_lp, pool_addr, False)
> elif coin_addr in self.registry.get_underlying_coins(pool_addr):
> self._add_liquidity(coin_addr, pool_addr, True)
129c171
< self._add_liquidity(coin_addr, pool_addr)
---
> assert False
diff -r ../lesson-23-reverts/margarita/tests/conftest.py margarita/tests/conftest.py
49c49
< dai._mint_for_testing(alice, 1_000_000 * 10 ** dai.decimals())
---
> dai._mint_for_testing(alice, 5_000 * 10 ** dai.decimals())
diff -r ../lesson-23-reverts/margarita/tests/integrative/test_stake.py margarita/tests/integrative/test_stake.py
5c5,6
< @given(pool_id=strategy("uint", min_value=0, max_value=41))
---
>
> @given(pool_id=strategy("uint", min_value=0, max_value=41, exclude=[4, 9, 16, 17, 21]))
8c9,12
< coin_list = registry.get_coins(pool) + registry.get_underlying_coins(pool)
---
> _coins = registry.get_coins(pool)
> _underlying = registry.get_underlying_coins(pool)
> coin_list = _coins + _underlying
>
11,14c15,17
< if registry.get_pool_asset_type(pool) > 0:
< return
< dai.transfer(stake, dai.balanceOf(alice), {'from': alice})
< stake.ape(dai, pool, {'from': alice})
---
>
> dai.transfer(stake, dai.balanceOf(alice), {"from": alice})
> stake.ape(dai, pool, {"from": alice})
5 changes: 5 additions & 0 deletions lesson-24-interactive-i/margarita/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
__pycache__
.history
.hypothesis/
build/
reports/
21 changes: 21 additions & 0 deletions lesson-24-interactive-i/margarita/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 brownie-mix

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
78 changes: 78 additions & 0 deletions lesson-24-interactive-i/margarita/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# token-mix

A bare-bones implementation of the Ethereum [ERC-20 standard](https://eips.ethereum.org/EIPS/eip-20), written in [Solidity](https://github.com/ethereum/solidity).

For [Vyper](https://github.com/vyperlang/vyper), check out [`vyper-token-mix`](https://github.com/brownie-mix/vyper-token-mix).

## Installation

1. [Install Brownie](https://eth-brownie.readthedocs.io/en/stable/install.html), if you haven't already.

2. Download the mix.

```bash
brownie bake token
```

## Basic Use

This mix provides a [simple template](contracts/Token.sol) upon which you can build your own token, as well as unit tests providing 100% coverage for core ERC20 functionality.

To interact with a deployed contract in a local environment, start by opening the console:

```bash
brownie console
```

Next, deploy a test token:

```python
>>> token = Token.deploy("Test Token", "TST", 18, 1e21, {'from': accounts[0]})
Transaction sent: 0x4a61edfaaa8ba55573603abd35403cf41291eca443c983f85de06e0b119da377
Gas price: 0.0 gwei Gas limit: 12000000
Token.constructor confirmed - Block: 1 Gas used: 521513 (4.35%)
Token deployed at: 0xd495633B90a237de510B4375c442C0469D3C161C
```

You now have a token contract deployed, with a balance of `1e21` assigned to `accounts[0]`:

```python
>>> token
<Token Contract '0xd495633B90a237de510B4375c442C0469D3C161C'>
>>> token.balanceOf(accounts[0])
1000000000000000000000
>>> token.transfer(accounts[1], 1e18, {'from': accounts[0]})
Transaction sent: 0xb94b219148501a269020158320d543946a4e7b9fac294b17164252a13dce9534
Gas price: 0.0 gwei Gas limit: 12000000
Token.transfer confirmed - Block: 2 Gas used: 51668 (0.43%)
<Transaction '0xb94b219148501a269020158320d543946a4e7b9fac294b17164252a13dce9534'>
```

## Testing

To run the tests:

```bash
brownie test
```

The unit tests included in this mix are very generic and should work with any ERC20 compliant smart contract. To use them in your own project, all you must do is modify the deployment logic in the [`tests/conftest.py::token`](tests/conftest.py) fixture.

## Resources

To get started with Brownie:

* Check out the other [Brownie mixes](https://github.com/brownie-mix/) that can be used as a starting point for your own contracts. They also provide example code to help you get started.
* ["Getting Started with Brownie"](https://medium.com/@iamdefinitelyahuman/getting-started-with-brownie-part-1-9b2181f4cb99) is a good tutorial to help you familiarize yourself with Brownie.
* For more in-depth information, read the [Brownie documentation](https://eth-brownie.readthedocs.io/en/stable/).


Any questions? Join our [Gitter](https://gitter.im/eth-brownie/community) channel to chat and share with others in the community.

## License

This project is licensed under the [MIT license](LICENSE).
15 changes: 15 additions & 0 deletions lesson-24-interactive-i/margarita/brownie-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# exclude SafeMath when calculating test coverage
# https://eth-brownie.readthedocs.io/en/v1.10.3/config.html#exclude_paths
networks:
default: mainnet-fork
mainnet-fork:
gas_price: 990000000000


reports:
exclude_contracts:
- SafeMath

dependencies:
- OpenZeppelin/[email protected]

29 changes: 29 additions & 0 deletions lesson-24-interactive-i/margarita/contracts/SafeMath.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
pragma solidity ^0.6.0;

library SafeMath {

function add(uint a, uint b) internal pure returns (uint c) {
c = a + b;
require(c >= a);
return c;
}

function sub(uint a, uint b) internal pure returns (uint c) {
require(b <= a);
c = a - b;
return c;
}

function mul(uint a, uint b) internal pure returns (uint c) {
c = a * b;
require(a == 0 || c / a == b);
return c;
}

function div(uint a, uint b) internal pure returns (uint c) {
require(b > 0);
c = a / b;
return c;
}

}
Loading

0 comments on commit a4639ef

Please sign in to comment.