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

BridgePool Factory #280

Merged
merged 97 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from 73 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
c1a868a
Fixed tests for new BridgePool architecture
Jul 5, 2022
59d4011
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Jul 5, 2022
d9284f2
Added multiple version management
Jul 6, 2022
e1c388d
Fixed BPFactory tests
Jul 6, 2022
5292843
Fixed SWAP error
Jul 6, 2022
3893476
Added control for unexistent implementation versions
Jul 7, 2022
e61f612
Fixed BridgePool DespositNotifier tests
Jul 7, 2022
6b73a65
Fixed lint warnings
Jul 7, 2022
9c7d009
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Jul 7, 2022
98ba772
Added more controls to BridgePoolFactory
Jul 8, 2022
7fdf98c
renamed bridge factory
z-j-lin Jul 11, 2022
45adfa4
fixed bridge router
z-j-lin Jul 11, 2022
957d244
Added support for ERC721 bridging
Jul 11, 2022
13eda0b
Merge remote-tracking branch 'gustavo/bridge-pool' into bridge-pool
z-j-lin Jul 11, 2022
13dc8e0
updated payAndDeposit
z-j-lin Jul 12, 2022
de80dc5
added static bridge pool address calculation to deterministic address
z-j-lin Jul 12, 2022
f3ec8f1
updated btoken and immutable auth
z-j-lin Jul 12, 2022
454c2fe
update calldata for routeDeposit
z-j-lin Jul 13, 2022
603c7f0
Moved deposit function to BToken contract
gusjavaz Jul 13, 2022
c5f79e7
Fixed all tests according to new design (deposit in BToken)
gusjavaz Jul 14, 2022
61d65e9
Fixed tests for ERC20
gusjavaz Jul 14, 2022
6193f5e
Fixed one failing ERC20 test
gusjavaz Jul 15, 2022
f8db4e9
Fixed lint errors
gusjavaz Jul 15, 2022
37907b2
Clean up and refactoring
Jul 15, 2022
f804a66
Clean up and refactoring
Jul 15, 2022
2da1220
Clean up and refactoring
Jul 15, 2022
2361da4
Clean up code for PR
Jul 18, 2022
b801806
Merge branch 'main' into bridge-pool
Jul 18, 2022
d18df69
Add merged files
Jul 18, 2022
2eb891e
Added two new tests
Jul 18, 2022
8bd5f04
Added circuit breaker and clean up code
Jul 19, 2022
aa82bcc
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Jul 19, 2022
321162b
Modify btokens to Eth for ERC deposit function
Jul 19, 2022
2a37829
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Jul 20, 2022
afa3ca1
Bindings
Jul 28, 2022
190ec39
Merge branch 'main' into bridge-pool
Jul 28, 2022
54b7e40
Merged lastest main
Jul 28, 2022
d6f7b37
moved deployment logic out of router and created bridgepoolFactory, c…
z-j-lin Aug 26, 2022
e3a64e5
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Aug 29, 2022
817a116
Refactoring to BridgePoolFactory
Aug 30, 2022
45b148b
Fixing tests
Aug 30, 2022
7eb5a25
Merge branch 'bridge-pool' of https://github.com/gusjavaz/alicenet in…
Aug 31, 2022
85aa25c
More test fixing
Aug 31, 2022
cc83254
Added support for ERC1155
Sep 1, 2022
d32afd8
Remove bindings
Sep 1, 2022
2180f07
Remove remix files
Sep 1, 2022
5464578
Fixed error in tests
Sep 2, 2022
f1e943c
Fixed lint errors
Sep 2, 2022
2b2980a
Discard Code of conduct
Sep 2, 2022
b24ad76
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Sep 2, 2022
922dfcd
Fix deposit & withdraw tests
Sep 2, 2022
725a559
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Sep 6, 2022
c22aa5c
Fixed some test errors
Sep 6, 2022
2554ca0
Separated factory from original bridge-pool branch
Sep 6, 2022
9642a84
modified bridgepool factory base to deploy pool logic
z-j-lin Sep 7, 2022
6ada64f
First Commit
Sep 19, 2022
024628f
fixed merge conflicts
z-j-lin Sep 21, 2022
0c02cf9
added pool logic deployment to factory
z-j-lin Sep 21, 2022
87e02a8
WIP: 9642a841 modified bridgepool factory base to deploy pool logic
z-j-lin Sep 22, 2022
a7ed293
Adapted test for new BridgePool deployment operation
Sep 23, 2022
92ca21a
Fixed Lint warnings
Sep 23, 2022
38de1a6
Fixed lint warnings
Sep 23, 2022
a7e348d
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Sep 23, 2022
f5f5086
Implemented loadFixture feature
Sep 23, 2022
eef6082
Rebuild with make generate
Sep 23, 2022
0f73735
Removed duplicate code
Sep 23, 2022
d03d793
Removed unused files
Sep 26, 2022
bd8a183
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
Sep 27, 2022
1b76513
Formatting
Sep 27, 2022
b27ea72
Remove getStaticPoolContractAddress
Sep 27, 2022
17007d7
Restored accusation_builder_test.go
Sep 27, 2022
d8a1b93
Removed unused files
Sep 27, 2022
288ebf5
Removed CAllAny
Sep 27, 2022
8c4f1a4
Removed code that belongs in bridge-pool-base
Sep 27, 2022
4a1af02
Refactoring
Sep 28, 2022
657f60e
Removed .only
Sep 28, 2022
dbdde1b
change logic deployment logic to track versions
z-j-lin Sep 28, 2022
da57895
ran formatter and generated bindings
z-j-lin Sep 28, 2022
eca7eb0
added natspec and get lates version function
z-j-lin Sep 28, 2022
5103d4e
ran format
z-j-lin Sep 28, 2022
fb2115e
added tests for coverage
z-j-lin Sep 28, 2022
7de5b46
added test coverage and get pool address function
z-j-lin Oct 14, 2022
e5011c1
removed nonexistent pool error
z-j-lin Oct 14, 2022
a083ae3
removed comment
z-j-lin Oct 14, 2022
dc4df40
cleanup
z-j-lin Oct 14, 2022
1735f4d
ran make generate
z-j-lin Oct 14, 2022
7220942
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
gusjavaz Nov 1, 2022
f4d65d5
Fix lint warnings
gusjavaz Nov 1, 2022
1408dc9
Merge remote-tracking branch 'upstream/main' into bridge-pool-factory
z-j-lin Nov 8, 2022
4d44697
Implementd reviewer's suggestions
gusjavaz Nov 9, 2022
a4e6368
Fixed lint warnings
gusjavaz Nov 9, 2022
84e1098
Added test for storage slot
gusjavaz Nov 9, 2022
4db30e5
Merge remote-tracking branch 'upstream/main' into bridge-pool-factory
z-j-lin Nov 9, 2022
569f0e0
Merge branch 'bridge-pool-factory' of github.com:gusjavaz/alicenet in…
z-j-lin Nov 9, 2022
8985b66
removed un needed immutable auth
z-j-lin Nov 9, 2022
6fa3db4
Merge branch 'main' of https://github.com/alicenet/alicenet into brid…
gusjavaz Nov 11, 2022
694adb7
Added alicenet factory as BP constructor parameter
gusjavaz Nov 11, 2022
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ dist/
scripts/generated
node_modules/
legacy/V1
bridge/dist
bridge/bindings
.deps
15 changes: 8 additions & 7 deletions application/objs/ds.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ func (b *DataStore) Value() (*uint256.Uint256, error) {
// Fee returns the fee stored in the object at the time of creation.
// This is the total fee associated with the DataStore object.
// Thus, we have
// Fee == perEpochFee*(numEpochs + 2)
//
// Fee == perEpochFee*(numEpochs + 2)
func (b *DataStore) Fee() (*uint256.Uint256, error) {
if b == nil {
return nil, errorz.ErrInvalid{}.New("ds.fee: ds not initialized")
Expand All @@ -264,7 +265,7 @@ func (b *DataStore) Fee() (*uint256.Uint256, error) {
// Given a DataStore with data of size dataSize bytes which are to be stored
// for of numEpochs, the value is
//
// value := (dataSize + BaseDatasizeConst) * (numEpochs + 2)
// value := (dataSize + BaseDatasizeConst) * (numEpochs + 2)
//
// Here, BaseDatasizeConst is a constant which includes the base cost of the
// actual storage object. Furthermore, we include 2 additional epochs into
Expand All @@ -273,14 +274,14 @@ func (b *DataStore) Fee() (*uint256.Uint256, error) {
// Given the base cost, we also want to be able to include additional fees.
// These fees would be on a per-epoch basis. Thus, we have the form
//
// valuePlusFee := (dataSize + BaseDatasizeConst + perEpochFee) * (numEpochs + 2)
// = (dataSize + BaseDatasizeConst) * (numEpochs + 2)
// + perEpochFee * (numEpochs + 2)
// = value + fee
// valuePlusFee := (dataSize + BaseDatasizeConst + perEpochFee) * (numEpochs + 2)
// = (dataSize + BaseDatasizeConst) * (numEpochs + 2)
// + perEpochFee * (numEpochs + 2)
// = value + fee
//
// with
//
// fee := perEpochFee * (numEpochs + 2)
// fee := perEpochFee * (numEpochs + 2)
//
// The fee is burned at creation.
func (b *DataStore) ValuePlusFee() (*uint256.Uint256, error) {
Expand Down
4 changes: 2 additions & 2 deletions application/objs/dspi.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func RewardDepositEquation(deposit *uint256.Uint256, dataSize32, epochInitial, e
//
// The simple equation is
//
// deposit = (dataSize + BaseDatasizeConst) * (2 + numEpochs)
// deposit = (dataSize + BaseDatasizeConst) * (2 + numEpochs)
func BaseDepositEquation(dataSize32, numEpochs32 uint32) (*uint256.Uint256, error) {
if dataSize32 > constants.MaxDataStoreSize {
// dataSize is too large so we do not perform any checks
Expand All @@ -397,7 +397,7 @@ func BaseDepositEquation(dataSize32, numEpochs32 uint32) (*uint256.Uint256, erro
//
// The simple equation is
//
// numEpochs = (deposit / (dataSize + BaseDatasizeConst)) - 2
// numEpochs = (deposit / (dataSize + BaseDatasizeConst)) - 2
//
// We have additional checks to ensure there is no integer overflow.
func NumEpochsEquation(dataSize32 uint32, deposit *uint256.Uint256) (uint32, error) {
Expand Down
66 changes: 66 additions & 0 deletions bridge/contracts/BridgePoolFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

import "contracts/libraries/errors/BridgePoolFactoryErrors.sol";
import "contracts/libraries/factory/BridgePoolFactoryBase.sol";

/// @custom:salt BridgePoolFactory
/// @custom:deploy-type deployUpgradeable
contract BridgePoolFactory is BridgePoolFactoryBase {
constructor() BridgePoolFactoryBase() {}

/**
* @notice Deploys a new bridge to pass tokens to our chain from the specified ERC contract.
* The pools are created as thin proxies (EIP1167) routing to versioned implementations identified by corresponding salt.
* @param tokenType_ type of token (1=ERC20, 2=ERC721)
* @param ercContract_ address of ERC20 source token contract
* @param implementationVersion_ version of BridgePool implementation to use
*/
function deployNewNativePool(
uint8 tokenType_,
address ercContract_,
uint16 implementationVersion_
) public onlyFactoryOrPublicPoolDeploymentEnabled {
gusjavaz marked this conversation as resolved.
Show resolved Hide resolved
_deployNewNativePool(tokenType_, ercContract_, implementationVersion_);
}

function deployPoolLogic(
uint8 tokenType_,
uint256 chainId_,
uint16 version_,
uint256 value_,
bytes calldata deployCode_
) public onlyFactory returns (address) {
return _deployPoolLogic(tokenType_, chainId_, version_, value_, deployCode_);
}

/**
* @dev enables or disables public pool deployment
**/
function togglePublicPoolDeployment() public onlyFactory {
_togglePublicPoolDeployment();
}

/**
* @notice calculates salt for a BridgePool contract based on ERC contract's address, tokenType, chainID and version_
* @param tokenContractAddr_ address of ERC Token contract
* @param tokenType_ type of token (1=ERC20, 2=ERC721)
* @param version_ version of the implementation
* @param chainID_ chain ID
* @return calculated calculated salt
*/
z-j-lin marked this conversation as resolved.
Show resolved Hide resolved
function getBridgePoolSalt(
address tokenContractAddr_,
uint8 tokenType_,
uint256 chainID_,
uint16 version_
) public pure returns (bytes32) {
return
BridgePoolAddressUtil.getBridgePoolSalt(
tokenContractAddr_,
tokenType_,
chainID_,
version_
);
}
}
10 changes: 10 additions & 0 deletions bridge/contracts/interfaces/IBridgePool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.11;

interface IBridgePool {
function initialize(address ercContract_) external;

function deposit(address msgSender, bytes calldata depositParameters) external;

function withdraw(bytes memory _txInPreImage, bytes[4] memory _proofs) external;
}
12 changes: 12 additions & 0 deletions bridge/contracts/libraries/errors/BridgePoolFactoryErrors.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

library BridgePoolFactoryErrors {
error FailedToDeployLogic();
error PoolVersionNotSupported(uint16 version);
error StaticPoolDeploymentFailed(bytes32 salt_);
error UnexistentBridgePoolImplementationVersion(uint16 version);
error UnableToDeployBridgePool(bytes32 salt_);
error InsufficientFunds();
error PublicPoolDeploymentTemporallyDisabled();
}
170 changes: 170 additions & 0 deletions bridge/contracts/libraries/factory/BridgePoolFactoryBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

import "contracts/utils/ImmutableAuth.sol";
import "contracts/libraries/errors/BridgePoolFactoryErrors.sol";
import "contracts/interfaces/IBridgePool.sol";
import "contracts/utils/BridgePoolAddressUtil.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

abstract contract BridgePoolFactoryBase is ImmutableFactory {
enum TokenType {
gusjavaz marked this conversation as resolved.
Show resolved Hide resolved
ERC20,
ERC721,
ERC1155
}
//chainid of layer 1 chain, 1 for ether mainnet
uint256 private immutable _chainID;
bool public publicPoolDeploymentEnabled;
address private _implementation;
mapping(string => address) internal _logicAddresses;
event BridgePoolCreated(address poolAddress, address token);

modifier onlyFactoryOrPublicPoolDeploymentEnabled() {
if (msg.sender != _factoryAddress() && !publicPoolDeploymentEnabled) {
revert BridgePoolFactoryErrors.PublicPoolDeploymentTemporallyDisabled();
}
_;
}

constructor() ImmutableFactory(msg.sender) {
_chainID = block.chainid;
}

// NativeERC20V!
/**
* @notice returns bytecode for a Minimal Proxy (EIP-1167) that routes to BridgePool implementation
*/
// solhint-disable-next-line
fallback() external {
address implementation_ = _implementation;
assembly {
let ptr := mload(0x40)
mstore(ptr, shl(176, 0x363d3d373d3d3d363d73)) //10
mstore(add(ptr, 10), shl(96, implementation_)) //20
mstore(add(ptr, 30), shl(136, 0x5af43d82803e903d91602b57fd5bf3)) //15
return(ptr, 45)
}
}

function _deployPoolLogic(
uint8 tokenType_,
uint256 chainId_,
uint16 version_,
uint256 value_,
bytes calldata deployCode_
) internal returns (address) {
address addr;
uint32 codeSize;
bool native = true;
if (chainId_ != _chainID) {
native = false;
}
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, deployCode_.offset, deployCode_.length)
addr := create(value_, ptr, deployCode_.length)
codeSize := extcodesize(addr)
}
if (codeSize == 0) {
revert BridgePoolFactoryErrors.FailedToDeployLogic();
}

_logicAddresses[_getImplementationAddressKey(tokenType_, version_, native)] = addr;
return addr;
}

/**
* @dev enables or disables public pool deployment
**/
function _togglePublicPoolDeployment() internal {
publicPoolDeploymentEnabled = !publicPoolDeploymentEnabled;
}

/**
* @notice Deploys a new bridge to pass tokens to layer 2 chain from the specified ERC contract.
* The pools are created as thin proxies (EIP1167) routing to versioned implementations identified by correspondent salt.
* @param tokenType_ type of token (0=ERC20, 1=ERC721, 2=ERC1155)
* @param ercContract_ address of ERC20 source token contract
* @param poolVersion_ version of BridgePool implementation to use
*/
function _deployNewNativePool(
uint8 tokenType_,
address ercContract_,
uint16 poolVersion_
) internal {
bool native = true;
//calculate the unique salt for the bridge pool
bytes32 bridgePoolSalt = BridgePoolAddressUtil.getBridgePoolSalt(
ercContract_,
tokenType_,
_chainID,
poolVersion_
);
//calculate the address of the pool's logic contract
address implementation = _logicAddresses[
_getImplementationAddressKey(tokenType_, poolVersion_, native)
];
_implementation = implementation;
//check if the logic exists for the specified pool
//TODO determin if this step is still necessary
z-j-lin marked this conversation as resolved.
Show resolved Hide resolved
uint256 implementationSize;
assembly {
implementationSize := extcodesize(implementation)
}
if (implementationSize == 0) {
revert BridgePoolFactoryErrors.PoolVersionNotSupported(poolVersion_);
}
address contractAddr = _deployStaticPool(bridgePoolSalt);
IBridgePool(contractAddr).initialize(ercContract_);
emit BridgePoolCreated(contractAddr, ercContract_);
}

/**
* @notice creates a BridgePool contract with specific salt and bytecode returned by this contract fallback
* @param salt_ salt of the implementation contract
* @return contractAddr the address of the BridgePool
*/
function _deployStaticPool(bytes32 salt_) internal returns (address contractAddr) {
uint256 contractSize;
assembly {
let ptr := mload(0x40)
mstore(ptr, shl(136, 0x5880818283335afa3d82833e3d82f3))
contractAddr := create2(0, ptr, 15, salt_)
contractSize := extcodesize(contractAddr)
}
if (contractSize == 0) {
revert BridgePoolFactoryErrors.StaticPoolDeploymentFailed(salt_);
}
return contractAddr;
}

/**
* @notice calculates salt for a BridgePool implementation contract based on tokenType and version
* @param tokenType_ type of token (0=ERC20, 1=ERC721, 2=ERC1155)
* @param version_ version of the implementation
* @param native_ boolean flag to specifier native or external token pools
* @return calculated key
*/
function _getImplementationAddressKey(
uint8 tokenType_,
uint16 version_,
bool native_
) internal pure returns (string memory) {
string memory key;
if (native_) {
key = "Native";
} else {
key = "External";
}
if (tokenType_ == uint8(TokenType.ERC20)) {
key = string.concat(key, "ERC20");
} else if (tokenType_ == uint8(TokenType.ERC721)) {
key = string.concat(key, "ERC721");
} else if (tokenType_ == uint8(TokenType.ERC1155)) {
key = string.concat(key, "ERC1155");
}
key = string.concat(key, "V", Strings.toString(version_));
return key;
}
}
54 changes: 54 additions & 0 deletions bridge/contracts/utils/BridgePoolAddressUtil.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

library BridgePoolAddressUtil {
enum TokenType {
gusjavaz marked this conversation as resolved.
Show resolved Hide resolved
ERC20,
ERC721,
ERC1155
}

/**
* @notice calculates salt for a BridgePool contract based on ERC contract's address, tokenType, chainID and version_
* @param tokenContractAddr_ address of ERC contract of BridgePool
* @param tokenType_ type of token (0=ERC20, 1=ERC721, 2=ERC1155)
* @param version_ version of the implementation
* @param chainID_ chain ID
* @return calculated calculated salt
*/
function getBridgePoolSalt(
address tokenContractAddr_,
uint8 tokenType_,
uint256 chainID_,
uint16 version_
) internal pure returns (bytes32) {
return
keccak256(
bytes.concat(
keccak256(abi.encodePacked(tokenContractAddr_)),
keccak256(abi.encodePacked(tokenType_)),
keccak256(abi.encodePacked(chainID_)),
keccak256(abi.encodePacked(version_))
)
);
}

function getBridgePoolAddress(bytes32 bridgePoolSalt_, address bridgeFactory_)
z-j-lin marked this conversation as resolved.
Show resolved Hide resolved
internal
pure
returns (address)
{
// works: 5880818283335afa3d82833e3d82f3
bytes32 initCodeHash = 0xf231e946a2f88d89eafa7b43271c54f58277304b93ac77d138d9b0bb3a989b6d;
return
address(
uint160(
uint256(
keccak256(
abi.encodePacked(hex"ff", bridgeFactory_, bridgePoolSalt_, initCodeHash)
)
)
)
);
}
}
Loading