Skip to content

Commit d664678

Browse files
authored
Merge pull request #1 from Reactive-Network/dec24-prerelease
Preparations for testnet refresh.
2 parents 40c6118 + cd135cd commit d664678

File tree

10 files changed

+83
-52
lines changed

10 files changed

+83
-52
lines changed

src/abstract-base/AbstractCallback.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ pragma solidity >=0.8.0;
55
import '../interfaces/IPayable.sol';
66
import './AbstractPayer.sol';
77

8+
/// @title Abstract base contract for contracts receiving the Reactive Network callbacks.
89
abstract contract AbstractCallback is AbstractPayer {
910
address internal rvm_id;
1011

1112
constructor(address _callback_sender) {
1213
rvm_id = msg.sender;
1314
vendor = IPayable(payable(_callback_sender));
15+
addAuthorizedSender(_callback_sender);
1416
}
1517

1618
modifier rvmIdOnly(address _rvm_id) {

src/abstract-base/AbstractPausableReactive.sol

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
pragma solidity >=0.8.0;
44

55
import '../interfaces/IReactive.sol';
6-
import '../interfaces/ISubscriptionService.sol';
76
import './AbstractReactive.sol';
87

8+
/// @title Abstract base contract for pausable reactive contracts.
99
abstract contract AbstractPausableReactive is IReactive, AbstractReactive {
1010
struct Subscription{
1111
uint256 chain_id;
@@ -23,13 +23,16 @@ abstract contract AbstractPausableReactive is IReactive, AbstractReactive {
2323
owner = msg.sender;
2424
}
2525

26+
/// @notice This function should return the list of subscriptions to pause/resume.
27+
/// @return The list of subscriptions to pause/resume.
2628
function getPausableSubscriptions() virtual internal view returns (Subscription[] memory);
2729

2830
modifier onlyOwner() {
2931
require(msg.sender == owner, 'Unauthorized');
3032
_;
3133
}
3234

35+
/// @notice Pauses the reactive contract by unsubscribing from events using the criteria provided by the implementation.
3336
function pause() external rnOnly onlyOwner {
3437
require(!paused, 'Already paused');
3538
Subscription[] memory subscriptions = getPausableSubscriptions();
@@ -46,6 +49,7 @@ abstract contract AbstractPausableReactive is IReactive, AbstractReactive {
4649
paused = true;
4750
}
4851

52+
/// @notice Resumed the reactive contract by subscribing to events using the criteria provided by the implementation.
4953
function resume() external rnOnly onlyOwner {
5054
require(paused, 'Not paused');
5155
Subscription[] memory subscriptions = getPausableSubscriptions();

src/abstract-base/AbstractPayer.sol

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,56 @@ pragma solidity >=0.8.0;
55
import '../interfaces/IPayer.sol';
66
import '../interfaces/IPayable.sol';
77

8+
/// @title Abstract base contract for contracts needing to handle payments to the system contract or callback proxies.
89
abstract contract AbstractPayer is IPayer {
910
IPayable internal vendor;
1011

12+
/// @notice ACL for addresses allowed to make callbacks and/or request payment.
13+
mapping(address => bool) senders;
14+
1115
constructor() {
1216
}
1317

18+
/// @inheritdoc IPayer
1419
receive() virtual external payable {
1520
}
1621

1722
modifier authorizedSenderOnly() {
18-
require(address(vendor) == address(0) || msg.sender == address(vendor), 'Authorized sender only');
23+
require(senders[msg.sender], 'Authorized sender only');
1924
_;
2025
}
2126

27+
/// @inheritdoc IPayer
2228
function pay(uint256 amount) external authorizedSenderOnly {
2329
_pay(payable(msg.sender), amount);
2430
}
2531

32+
/// @notice Automatically cover the outstanding debt to the system contract or callback proxy, provided the contract has sufficient funds.
2633
function coverDebt() external {
2734
uint256 amount = vendor.debt(address(this));
2835
_pay(payable(vendor), amount);
2936
}
3037

38+
/// @notice Attempts to safely transfer the specified sum to the given address.
39+
/// @param recipient Address of the transfer's recipient.
40+
/// @param amount Amount to be transferred.
3141
function _pay(address payable recipient, uint256 amount) internal {
3242
require(address(this).balance >= amount, 'Insufficient funds');
3343
if (amount > 0) {
3444
(bool success,) = payable(recipient).call{value: amount}(new bytes(0));
3545
require(success, 'Transfer failed');
3646
}
3747
}
48+
49+
/// @notice Adds the given address to the ACL.
50+
/// @param sender Sender address to add.
51+
function addAuthorizedSender(address sender) internal {
52+
senders[sender] = true;
53+
}
54+
55+
/// @notice Removes the given address from the ACL.
56+
/// @param sender Sender address to remove.
57+
function removeAuthorizedSender(address sender) internal {
58+
senders[sender] = false;
59+
}
3860
}

src/abstract-base/AbstractReactive.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,22 @@
33
pragma solidity >=0.8.0;
44

55
import '../interfaces/IReactive.sol';
6-
import '../interfaces/IPayable.sol';
76
import '../interfaces/ISystemContract.sol';
87
import './AbstractPayer.sol';
98

9+
/// @title Abstract base contract for reactive contracts.
1010
abstract contract AbstractReactive is IReactive, AbstractPayer {
1111
uint256 internal constant REACTIVE_IGNORE = 0xa65f96fc951c35ead38878e0f0b7a3c744a6f5ccc1476b313353ce31712313ad;
1212
ISystemContract internal constant SERVICE_ADDR = ISystemContract(payable(0x0000000000000000000000000000000000fffFfF));
1313

14-
/**
15-
* Indicates whether this is a ReactVM instance of the contract.
16-
*/
14+
/// @notice Indicates whether this is a ReactVM instance of the contract.
1715
bool internal vm;
1816

1917
ISystemContract internal service;
2018

2119
constructor() {
2220
vendor = service = SERVICE_ADDR;
21+
addAuthorizedSender(address(SERVICE_ADDR));
2322
detectVm();
2423
}
2524

@@ -33,6 +32,7 @@ abstract contract AbstractReactive is IReactive, AbstractPayer {
3332
_;
3433
}
3534

35+
/// @notice Determines whether this copy of the contract is deployed to an RVM or the top-level Reactive Network by checking for the presence of the system contract at the predetermined address.
3636
function detectVm() internal {
3737
uint256 size;
3838
// solhint-disable-next-line no-inline-assembly

src/interfaces/IPayable.sol

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
pragma solidity >=0.8.0;
44

5+
/// @title Common interface for the system contract and the callback proxy, allows contracts to check and pay their debts.
56
interface IPayable {
6-
// @notice Allows contracts to pay their debts and resume subscriptions.
7+
/// @notice Allows contracts to pay their debts and resume subscriptions.
78
receive() external payable;
89

9-
// @notice Allows reactive contracts to check their outstanding debt.
10-
// @param _contract Reactive contract's address.
10+
/// @notice Allows reactive contracts to check their outstanding debt.
11+
/// @param _contract Reactive contract's address.
12+
/// @return Reactive contract's current debt due to unpaid reactive transactions and/or callbacks.
1113
function debt(address _contract) external view returns (uint256);
1214
}

src/interfaces/IPayer.sol

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
pragma solidity >=0.8.0;
44

5+
/// @title Common interface for the contracts that need to pay for system contract's or proxies' services.
56
interface IPayer {
6-
// @dev Make sure to check the msg.sender
7+
/// @notice Method called by the system contract and/or proxies when payment is due.
8+
/// @dev Make sure to check the msg.sender.
9+
/// @param amount Amount owed due to reactive transactions and/or callbacks.
710
function pay(uint256 amount) external;
811

12+
/// @notice Allows the reactive contracts and callback contracts to receive funds for their operational expenses.
913
receive() external payable;
1014
}

src/interfaces/IReactive.sol

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,32 @@ pragma solidity >=0.8.0;
44

55
import './IPayer.sol';
66

7-
// @title Interface for reactive contracts.
8-
// @notice Reactive contracts receive notifications about new events matching the criteria of their event subscriptions.
7+
/// @title Interface for reactive contracts.
8+
/// @notice Reactive contracts receive notifications about new events matching the criteria of their event subscriptions.
99
interface IReactive is IPayer {
10+
struct LogRecord {
11+
uint256 chain_id;
12+
address _contract;
13+
uint256 topic_0;
14+
uint256 topic_1;
15+
uint256 topic_2;
16+
uint256 topic_3;
17+
bytes data;
18+
uint256 block_number;
19+
uint256 op_code;
20+
uint256 block_hash;
21+
uint256 tx_hash;
22+
uint256 log_index;
23+
}
24+
1025
event Callback(
1126
uint256 indexed chain_id,
1227
address indexed _contract,
1328
uint64 indexed gas_limit,
1429
bytes payload
1530
);
1631

17-
// @notice Entry point for handling new event notifications.
18-
// @param chain_id EIP155 source chain ID for the event (as a `uint256`).
19-
// @param _contract Address of the originating contract for the received event.
20-
// @param topic_0 Topic 0 of the event (or `0` for `LOG0`).
21-
// @param topic_1 Topic 1 of the event (or `0` for `LOG0` and `LOG1`).
22-
// @param topic_2 Topic 2 of the event (or `0` for `LOG0` .. `LOG2`).
23-
// @param topic_3 Topic 3 of the event (or `0` for `LOG0` .. `LOG3`).
24-
// @param data Event data as a byte array.
25-
// @param block_number Block number where the log record is located in its chain of origin.
26-
// @param op_code Number of topics in the log record (0 to 4).
27-
function react(
28-
uint256 chain_id,
29-
address _contract,
30-
uint256 topic_0,
31-
uint256 topic_1,
32-
uint256 topic_2,
33-
uint256 topic_3,
34-
bytes calldata data,
35-
uint256 block_number,
36-
uint256 op_code
37-
) external;
32+
/// @notice Entry point for handling new event notifications.
33+
/// @param log Data structure containing the information about the intercepted log record.
34+
function react(LogRecord calldata log) external;
3835
}

src/interfaces/ISubscriptionService.sol

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@ pragma solidity >=0.8.0;
44

55
import './IPayable.sol';
66

7-
// @title Interface for event subscription service.
8-
// @notice Reactive contracts receive notifications about new events matching the criteria of their event subscriptions.
7+
/// @title Interface for event subscription service.
8+
/// @notice Reactive contracts receive notifications about new events matching the criteria of their event subscriptions.
99
interface ISubscriptionService is IPayable {
10-
// @notice Subscribes the calling contract to receive events matching the criteria specified.
11-
// @param chain_id EIP155 source chain ID for the event (as a `uint256`), or `0` for all chains.
12-
// @param _contract Contract address to monitor, or `0` for all contracts.
13-
// @param topic_0 Topic 0 to monitor, or `REACTIVE_IGNORE` for all topics.
14-
// @param topic_1 Topic 1 to monitor, or `REACTIVE_IGNORE` for all topics.
15-
// @param topic_2 Topic 2 to monitor, or `REACTIVE_IGNORE` for all topics.
16-
// @param topic_3 Topic 3 to monitor, or `REACTIVE_IGNORE` for all topics.
17-
// @dev At least one of criteria above must be non-`REACTIVE_IGNORE`.
18-
// @dev Will allow duplicate or overlapping subscriptions, clients must ensure idempotency.
10+
/// @notice Subscribes the calling contract to receive events matching the criteria specified.
11+
/// @param chain_id EIP155 source chain ID for the event (as a `uint256`), or `0` for all chains.
12+
/// @param _contract Contract address to monitor, or `0` for all contracts.
13+
/// @param topic_0 Topic 0 to monitor, or `REACTIVE_IGNORE` for all topics.
14+
/// @param topic_1 Topic 1 to monitor, or `REACTIVE_IGNORE` for all topics.
15+
/// @param topic_2 Topic 2 to monitor, or `REACTIVE_IGNORE` for all topics.
16+
/// @param topic_3 Topic 3 to monitor, or `REACTIVE_IGNORE` for all topics.
1917
function subscribe(
2018
uint256 chain_id,
2119
address _contract,
@@ -25,14 +23,13 @@ interface ISubscriptionService is IPayable {
2523
uint256 topic_3
2624
) external;
2725

28-
// @notice Removes active subscription of the calling contract, matching the criteria specified, if one exists.
29-
// @param chain_id Chain ID criterion of the original subscription.
30-
// @param _contract Contract address criterion of the original subscription.
31-
// @param topic_0 Topic 0 criterion of the original subscription.
32-
// @param topic_1 Topic 0 criterion of the original subscription.
33-
// @param topic_2 Topic 0 criterion of the original subscription.
34-
// @param topic_3 Topic 0 criterion of the original subscription.
35-
// @dev This is very expensive.
26+
/// @notice Removes active subscription of the calling contract, matching the criteria specified, if one exists.
27+
/// @param chain_id Chain ID criterion of the original subscription.
28+
/// @param _contract Contract address criterion of the original subscription.
29+
/// @param topic_0 Topic 0 criterion of the original subscription.
30+
/// @param topic_1 Topic 0 criterion of the original subscription.
31+
/// @param topic_2 Topic 0 criterion of the original subscription.
32+
/// @param topic_3 Topic 0 criterion of the original subscription.
3633
function unsubscribe(
3734
uint256 chain_id,
3835
address _contract,

src/interfaces/ISystemContract.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ pragma solidity >=0.8.0;
55
import './IPayable.sol';
66
import './ISubscriptionService.sol';
77

8+
/// @title Interface for the Reactive Network's system contract.
89
interface ISystemContract is IPayable, ISubscriptionService {
910
}

src/libraries/SystemLib.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
pragma solidity >=0.8.0;
44

5+
/// @notice Gets the current implementation address of the system contract by calling the node's custom function on address `0x64`.
6+
/// @return The address of the current implementation of the system contract.
57
function getSystemContractImpl() returns (address) {
68
(bool success, bytes memory ret) = address(0x64).call(abi.encode(block.number));
79
require(success && ret.length == 0x20, 'Failure');

0 commit comments

Comments
 (0)