Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
632 changes: 632 additions & 0 deletions EIPs/eip-7702/README.md

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions EIPs/eip-7702/contracts/attachCode/Delegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
* @title Delegation
* @author Pavel Naydanov
*/
contract Delegation {
uint256 private _value;

constructor(uint256 initialValue) {
_value = initialValue;
}

function setValue(uint256 newValue) external {
_value = newValue;
}

function getValue() external view returns (uint256) {
return _value;
}
}
37 changes: 37 additions & 0 deletions EIPs/eip-7702/contracts/attachCode/Delegation.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import {Test, console, Vm, StdCheats} from "forge-std/Test.sol";
import {Delegation} from "./Delegation.sol";

contract DelegationTest is Test {
uint256 private constant _INITIAL_VALUE = 1;
Delegation public delegation;

StdCheats.Account public user;
StdCheats.Account public operator;

function setUp() external {
delegation = new Delegation(_INITIAL_VALUE);

user = makeAccount("User");
operator = makeAccount("Operator");
}

function test_attachCode() external {
// Проверяем наличие кода у EOA
console.logBytes(user.addr.code); // 0x

// Симулируем подписание транзакции на прикрепление кода пользователем
Vm.SignedDelegation memory signedDelegation = vm.signDelegation(address(delegation), user.key);

vm.startBroadcast(operator.key);

// Отправляем транзакцию на прикрепление кода к user. Обратить внимание, что это делает operator, а не user
vm.attachDelegation(signedDelegation);

vm.stopBroadcast();

console.logBytes(user.addr.code); // 0xef01005615deb798bb3e4dfa0139dfa1b3d433cc23b72f
}
}
31 changes: 31 additions & 0 deletions EIPs/eip-7702/contracts/condition/Delegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

contract Target {
uint256 private _value;

error EOACallIsNotAllowed();

function setValue(uint256 newValue) external {
if (tx.origin == msg.sender) {
revert EOACallIsNotAllowed();
}

_value = newValue;
}

function getValue() external view returns (uint256) {
return _value;
}
}

/**
* @title Delegation
* @author Pavel Naydanov
* @notice Показываем, что теперь EOA обходит проверку tx.origin == msg.sender
*/
contract Delegation {
function setValue(address target, uint256 value) external {
Target(target).setValue(value);
}
}
49 changes: 49 additions & 0 deletions EIPs/eip-7702/contracts/condition/Delegation.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import {Test, console, Vm, StdCheats} from "forge-std/Test.sol";
import {Delegation, Target} from "./Delegation.sol";

contract DelegationTest is Test {
Delegation public delegation;
Target public target;

StdCheats.Account public user;
StdCheats.Account public operator;

function setUp() external {
target = new Target();
delegation = new Delegation();

user = makeAccount("User");
operator = makeAccount("Operator");

vm.label(address(delegation), "Delegation");
vm.label(address(this), "address(this)");
vm.label(address(target), "Target");
vm.label(user.addr, "User");
vm.label(operator.addr, "Operator");
}

function test_checkCondition(uint256 value) external {
Vm.SignedDelegation memory signedDelegation = vm.signDelegation(address(delegation), user.key);

// Симулируем, что пользователь напрямую вызывает целевой контракт и транзакция ревертится
vm.expectRevert(Target.EOACallIsNotAllowed.selector);
vm.prank(user.addr, user.addr);
target.setValue(value);

// Operator прикрепляет смарт-контракт Delegation к user
vm.startBroadcast(operator.key);
vm.attachDelegation(signedDelegation);
vm.stopBroadcast();

// Operator вызывает функцию setValue на контракте Delegation от имени user,
// которая установит value на смарт-контракте Target
vm.prank(operator.addr, operator.addr);
Delegation(user.addr).setValue(address(target), value);

// Проверяем, что значение установлено (проверку обошли)
assertEq(target.getValue(), value);
}
}
9 changes: 9 additions & 0 deletions EIPs/eip-7702/contracts/receiveNativeCurrency/Delegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
* @title Delegation
* @author Pavel Naydanov
* @notice Не реализована функция receive() для получения нативной валюты
*/
contract Delegation {}
38 changes: 38 additions & 0 deletions EIPs/eip-7702/contracts/receiveNativeCurrency/Delegation.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import {Test, console, Vm, StdCheats} from "forge-std/Test.sol";
import {Delegation} from "./Delegation.sol";

contract DelegationTest is Test {
Delegation public delegation;

StdCheats.Account public user;
StdCheats.Account public operator;

function setUp() external {
delegation = new Delegation();

user = makeAccount("User");
operator = makeAccount("Operator");

vm.label(address(delegation), "Delegation");
vm.label(address(this), "address(this)");
vm.label(user.addr, "User");
vm.label(operator.addr, "Operator");
}

function test_checkSendNativeCurrency(uint256 value) external {
Vm.SignedDelegation memory signedDelegation = vm.signDelegation(address(delegation), user.key);

// Operator прикрепляет смарт-контракт Delegation к user
vm.startBroadcast(operator.key);
vm.attachDelegation(signedDelegation);
vm.stopBroadcast();

// Пытаемся отправить нативную валюту, транзакция ревертнется
(bool success,) = user.addr.call{value: value}("");

assertFalse(success);
}
}
36 changes: 36 additions & 0 deletions EIPs/eip-7702/contracts/storageCollision/Delegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
* @title Delegation first
* @author Pavel Naydanov
* @notice Показываем работу хранилища
*/
contract DelegationFirst {
uint256 private _value;

function setValue(uint256 newValue) external {
_value = newValue;
}

function getValue() external view returns (uint256) {
return _value;
}
}

/**
* @title Delegation second
* @author Pavel Naydanov
* @notice Показываем работу хранилища
*/
contract DelegationSecond {
bytes32 private _hashValue;

function setHash(bytes32 hashValue) external {
_hashValue = hashValue;
}

function getHash() external view returns (bytes32) {
return _hashValue;
}
}
49 changes: 49 additions & 0 deletions EIPs/eip-7702/contracts/storageCollision/Delegation.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import {Test, console, Vm, StdCheats} from "forge-std/Test.sol";
import {DelegationFirst, DelegationSecond} from "./Delegation.sol";

contract DelegationTest is Test {
uint256 private constant _INITIAL_VALUE = 1;
DelegationFirst public delegationFirst;
DelegationSecond public delegationSecond;

StdCheats.Account public user;
StdCheats.Account public operator;

function setUp() external {
delegationFirst = new DelegationFirst();
delegationSecond = new DelegationSecond();

user = makeAccount("User");
operator = makeAccount("Operator");
}

function test_storageCollision(uint256 value, bytes32 hashValue) external {
// Прикрепляем первый смарт-контракт
vm.startBroadcast(operator.key);
vm.signAndAttachDelegation(address(delegationFirst), user.key);
vm.stopBroadcast();

// Устанавливаем значение в хранилище смарт-контракта
DelegationFirst(user.addr).setValue(value);
assertEq(DelegationFirst(user.addr).getValue(), value);

// Прикрепляем второй смарт-контракт
vm.startBroadcast(operator.key);
vm.signAndAttachDelegation(address(delegationSecond), user.key);
vm.stopBroadcast();

// Устанавливаем hash в хранилище смарт-контракта
DelegationSecond(user.addr).setHash(hashValue);
assertEq(DelegationSecond(user.addr).getHash(), hashValue);

// Прикрепляем первый смарт-контракт повторно
vm.startBroadcast(operator.key);
vm.signAndAttachDelegation(address(delegationFirst), user.key);
vm.stopBroadcast();

assertNotEq(DelegationFirst(user.addr).getValue(), value); // Доказывает что значение было изменено
}
}
25 changes: 25 additions & 0 deletions EIPs/eip-7702/contracts/storageExample/Delegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
* @title Delegation
* @author Pavel Naydanov
* @notice Показываем работу хранилища и контекста вызовов при делегировании вызовов через EOA
*/
contract Delegation {
uint256 private _value;

constructor(uint256 initialValue) {
_value = initialValue;
}

// Записываем значение в хранилище
function setValue(uint256 newValue) external {
_value = newValue;
}

// Получаем значение из хранилища
function getValue() external view returns (uint256) {
return _value;
}
}
26 changes: 26 additions & 0 deletions EIPs/eip-7702/contracts/work-with-native-currency/Delegation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
* @title Delegation
* @author Pavel Naydanov
* @notice Показываем работу c нативной валютой
*/
contract Delegation {
/// Оставляем нативную валюту на адресе user
function buy() external payable {}

/// @notice Пересылаем нативную валюту на смарт-контракт target
function buyAndSendToTarget(address target) external payable {
(bool success, ) = target.call{value: msg.value}("");

if (!success) {
revert();
}
}
}

contract Target {
// Разрешаем принимать нативную валюту
receive() external payable {}
}
49 changes: 49 additions & 0 deletions EIPs/eip-7702/contracts/work-with-native-currency/Delegation.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import {Test, console, Vm, StdCheats} from "forge-std/Test.sol";
import {Delegation, Target} from "./Delegation.sol";

contract DelegationTest is Test {
Delegation public delegation;
Target public target;

StdCheats.Account public user;
StdCheats.Account public operator;

function setUp() external {
delegation = new Delegation();
target = new Target();

user = makeAccount("User");
operator = makeAccount("Operator");
}

function test_workWithNativeCurrency_buy(uint256 value) external {
deal(operator.addr, value);

vm.startBroadcast(operator.key);
vm.signAndAttachDelegation(address(delegation), user.key);
vm.stopBroadcast();

vm.prank(operator.addr);
Delegation(user.addr).buy{value: value}();

// Нативная валюта остается на балансе пользователя
assertEq(user.addr.balance, value);
}

function test_workWithNativeCurrency_buyAndSendToTarget(uint256 value) external {
deal(operator.addr, value);

vm.startBroadcast(operator.key);
vm.signAndAttachDelegation(address(delegation), user.key);
vm.stopBroadcast();

vm.prank(operator.addr);
Delegation(user.addr).buyAndSendToTarget{value: value}(address(target));

// Нативная валюта остается на балансе target смарт-контракта
assertEq(address(target).balance, value);
}
}
Binary file added EIPs/eip-7702/images/eip-7702-and-erc-4337.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added EIPs/eip-7702/images/eip-7702-etherscan-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added EIPs/eip-7702/images/eip-7702-etherscan-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added EIPs/eip-7702/images/eip-7702-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added EIPs/eip-7702/images/eip-7702-storage-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading