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
15 changes: 15 additions & 0 deletions src/IntuitionFeeProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ contract IntuitionFeeProxy {
uint256[] calldata assets,
uint256 curveId
) external payable returns (bytes32[] memory atomIds) {
_validateReceiver(receiver);

if (data.length != assets.length) {
revert Errors.IntuitionFeeProxy_WrongArrayLengths();
}
Expand Down Expand Up @@ -271,6 +273,8 @@ contract IntuitionFeeProxy {
uint256[] calldata assets,
uint256 curveId
) external payable returns (bytes32[] memory tripleIds) {
_validateReceiver(receiver);

if (subjectIds.length != predicateIds.length ||
predicateIds.length != objectIds.length ||
objectIds.length != assets.length) {
Expand Down Expand Up @@ -337,6 +341,8 @@ contract IntuitionFeeProxy {
uint256 curveId,
uint256 minShares
) external payable returns (uint256 shares) {
_validateReceiver(receiver);

// Must send more than just the fixed fee
if (msg.value <= depositFixedFee) {
revert Errors.IntuitionFeeProxy_InsufficientValue();
Expand Down Expand Up @@ -384,6 +390,8 @@ contract IntuitionFeeProxy {
uint256[] calldata assets,
uint256[] calldata minShares
) external payable returns (uint256[] memory shares) {
_validateReceiver(receiver);

if (termIds.length != curveIds.length ||
curveIds.length != assets.length ||
assets.length != minShares.length) {
Expand Down Expand Up @@ -483,6 +491,13 @@ contract IntuitionFeeProxy {
}
}

/// @notice Ensure fee proxy users cannot send their shares to an arbitrary receiver
function _validateReceiver(address receiver) internal view {
if (receiver != msg.sender) {
revert Errors.IntuitionFeeProxy_ReceiverMustBeSender();
}
}

/// @notice Sum array of uint256 values
/// @param arr Array to sum
/// @return sum Total sum
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ library Errors {

/// @notice Fee percentage exceeds maximum allowed (100%)
error IntuitionFeeProxy_FeePercentageTooHigh();

/// @notice Receiver must match the transaction sender
error IntuitionFeeProxy_ReceiverMustBeSender();
}
51 changes: 51 additions & 0 deletions test/IntuitionFeeProxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,18 @@ describe("IntuitionFeeProxy", function () {
proxy.connect(user).createAtoms(user.address, data, assets, curveId, { value: ethers.parseEther("0.01") })
).to.be.revertedWithCustomError(proxy, "IntuitionFeeProxy_InsufficientValue");
});

it("Should reject createAtoms when receiver is not the sender", async function () {
const { proxy, user, nonAdmin } = await loadFixture(deployFixture);

const data = [ethers.toUtf8Bytes("ipfs://atom1")];
const assets = [0n];
const curveId = 1n;

await expect(
proxy.connect(user).createAtoms(nonAdmin.address, data, assets, curveId)
).to.be.revertedWithCustomError(proxy, "IntuitionFeeProxy_ReceiverMustBeSender");
});
});

describe("Proxy Functions - createTriples", function () {
Expand Down Expand Up @@ -308,6 +320,20 @@ describe("IntuitionFeeProxy", function () {
proxy.connect(user).createTriples(user.address, subjectIds, predicateIds, objectIds, assets, curveId, { value: ethers.parseEther("10") })
).to.be.revertedWithCustomError(proxy, "IntuitionFeeProxy_WrongArrayLengths");
});

it("Should reject createTriples when receiver is not the sender", async function () {
const { proxy, user, nonAdmin } = await loadFixture(deployFixture);

const subjectIds = [ethers.zeroPadValue("0x01", 32)];
const predicateIds = [ethers.zeroPadValue("0x02", 32)];
const objectIds = [ethers.zeroPadValue("0x03", 32)];
const assets = [0n];
const curveId = 1n;

await expect(
proxy.connect(user).createTriples(nonAdmin.address, subjectIds, predicateIds, objectIds, assets, curveId)
).to.be.revertedWithCustomError(proxy, "IntuitionFeeProxy_ReceiverMustBeSender");
});
});

describe("Proxy Functions - deposit", function () {
Expand Down Expand Up @@ -359,6 +385,17 @@ describe("IntuitionFeeProxy", function () {
expect(await proxy.getMultiVaultAmountFromValue(DEPOSIT_FEE)).to.equal(0n);
expect(await proxy.getMultiVaultAmountFromValue(ethers.parseEther("0.05"))).to.equal(0n);
});

it("Should reject deposit when receiver is not the sender", async function () {
const { proxy, user, nonAdmin } = await loadFixture(deployFixture);

const termId = ethers.zeroPadValue("0x01", 32);
const totalToSend = await proxy.getTotalDepositCost(ethers.parseEther("1"));

await expect(
proxy.connect(user).deposit(nonAdmin.address, termId, 1n, 0n, { value: totalToSend })
).to.be.revertedWithCustomError(proxy, "IntuitionFeeProxy_ReceiverMustBeSender");
});
});

describe("Proxy Functions - depositBatch", function () {
Expand Down Expand Up @@ -396,6 +433,20 @@ describe("IntuitionFeeProxy", function () {
proxy.connect(user).depositBatch(user.address, termIds, curveIds, assets, minShares, { value: ethers.parseEther("20") })
).to.be.revertedWithCustomError(proxy, "IntuitionFeeProxy_WrongArrayLengths");
});

it("Should reject depositBatch when receiver is not the sender", async function () {
const { proxy, user, nonAdmin } = await loadFixture(deployFixture);

const termIds = [ethers.zeroPadValue("0x01", 32)];
const curveIds = [1n];
const assets = [ethers.parseEther("1")];
const minShares = [0n];
const totalRequired = ethers.parseEther("1") + await proxy.calculateDepositFee(1n, ethers.parseEther("1"));

await expect(
proxy.connect(user).depositBatch(nonAdmin.address, termIds, curveIds, assets, minShares, { value: totalRequired })
).to.be.revertedWithCustomError(proxy, "IntuitionFeeProxy_ReceiverMustBeSender");
});
});

describe("View Functions (Passthrough)", function () {
Expand Down